noip2013day2题解


描述

随着智能手机的日益普及,人们对无线网的需求日益增大。某城市决定对城市内的公共场所覆盖无线网。

假设该城市的布局为由严格平行的 129 条东西向街道和 129 条南北向街道所形成的网格状,并且相邻的平行街道之间的距离都是恒定值 1 。东西向街道从北到南依次编号为0,1,2…128,南北向街道从西到东依次编号为 0,1,2…128。

东西向街道和南北向街道相交形成路口,规定编号为 x 的南北向街道和编号为 y 的东西向街道形成的路口的坐标是(x, y)。在某些路口存在一定数量的公共场所。

由于政府财政问题,只能安装一个大型无线网络发射器。该无线网络发射器的传播范围是一个以该点为中心,边长为 2*d 的正方形。传播范围包括正方形边界。

例如下图是一个 d = 1 的无线网络发射器的覆盖范围示意图。

图片

现在政府有关部门准备安装一个传播参数为 d 的无线网络发射器,希望你帮助他们在城 市内找出合适的安装地点,使得覆盖的公共场所最多。

格式

输入格式

第一行包含一个整数 d,表示无线网络发射器的传播距离。

第二行包含一个整数 n,表示有公共场所的路口数目。

接下来 n 行,每行给出三个整数 x, y, k, 中间用一个空格隔开,分别代表路口的坐标(x, y)以及该路口公共场所的数量。同一坐标只会给出一次。

输出格式

输出一行,包含两个整数,用一个空格隔开,分别表示能覆盖最多公共场所的安装地点方案数,以及能覆盖的最多公共场所的数量。

样例1

样例输入1[复制]

 
1
2
4 4 10
6 6 20

样例输出1[复制]

 
1 30

限制

对于 100%的数据,1 ≤ d ≤ 20,1 ≤ n ≤ 20, 0 ≤ x ≤ 128, 0 ≤ y ≤ 128, 0 < k ≤ 1,000,000。

枚举每一个点

 1 #include
 2 #include
 3 #include 
 4 #include
 5 using namespace std;
 6 
 7 int d,n,map[25][3];
 8 long long maxsum=-1;
 9 int count=0;
10 
11 int main()
12 {
13     cin>>d>>n;
14     for(int i=1;i<=n;i++)cin>>map[i][0]>>map[i][1]>>map[i][2];
15     for(int x=0;x<=128;x++)
16      for(int y=0;y<=128;y++)
17      {
18          long long sum=0;
19          for(int i=1;i<=n;i++)
20           if(x-d<=map[i][0]&&map[i][0]<=x+d
21              &&y-d<=map[i][1]&&map[i][1]<=y+d)sum+=map[i][2];
22          if(maxsum<sum)
23          {
24              maxsum=sum;
25              count=1;
26          }
27          else if(sum==maxsum)count++;
28      }
29     cout<" "<endl;
30     return 0;
31 }

描述

在有向图 G 中,每条边的长度均为 1,现给定起点和终点,请你在图中找一条从起点到 终点的路径,该路径满足以下条件:

  1. 路径上的所有点的出边所指向的点都直接或间接与终点连通。
  2. 在满足条件 1 的情况下使路径最短。

注意:图 G 中可能存在重边和自环,题目保证终点没有出边。 请你输出符合条件的路径的长度。

格式

输入格式

第一行有两个用一个空格隔开的整数 n 和 m,表示图有 n 个点和 m 条边。

接下来的 m 行每行 2 个整数 x、y,之间用一个空格隔开,表示有一条边从点 x 指向点y。

最后一行有两个用一个空格隔开的整数 s、t,表示起点为 s,终点为 t。

输出格式

输出只有一行,包含一个整数,表示满足题目描述的最短路径的长度。

如果这样的路径不存在,输出-1。

样例1

样例输入1[复制]

 
3 2
1 2
2 1
1 3

样例输出1[复制]

 
-1

样例2

样例输入2[复制]

 
6 6
1 2
1 3
2 6
2 5
4 5
3 4
1 5

样例输出2[复制]

 
3

限制

对于 30%的数据,0 < n ≤ 10,0 < m ≤ 20;

对于 60%的数据,0 < n ≤ 100,0 < m ≤ 2000;

对于 100%的数据,0 < n ≤ 10,000,0 < m ≤ 200,000,0 < x,y,s,t ≤ n,x ≠ t。

提示

【输入输出样例1说明】

图片

如上图所示,箭头表示有向道路,圆点表示城市。起点 1 与终点 3 不连通,所以满足题目描述的路径不存在,故输出-1。

【输入输出样例2说明】

图片

如上图所示,满足条件的路径为 1->3->4->5。注意点 2 不能在答案路径中,因为点 2 连了一条边到点 6,而点 6 不与终点 5 连通。

多来次DFS即可

  1 #include
  2 #include
  3 int n,m;
  4 int begin[10010];
  5 int cou=0;
  6 int flag[10010];
  7 int ifin[10010];
  8 int dis[10010];
  9 int getget[10010];
 10 
 11 struct edge
 12 {
 13     int b,weight,next;
 14 };
 15 edge E[400010];
 16 
 17 int addedge(int a,int b)
 18 {
 19     E[cou].b=b;
 20     E[cou].next=begin[a];
 21     E[cou].weight=1;
 22     begin[a]=cou;
 23     cou++;
 24     E[cou].b=a;
 25     E[cou].weight=-1;
 26     E[cou].next=begin[b];
 27     begin[b]=cou;
 28     cou++;
 29 }
 30 
 31 class queue
 32 {
 33 private:
 34     int rear,front,size;
 35     int q[100000];
 36 public:
 37     queue()
 38     {
 39         rear=-1;
 40         front=size=0;
 41     }
 42     int Dequeue()
 43     {
 44         int x=q[front];
 45         front++;
 46         size--;
 47         return x;
 48     }
 49     void Enqueue(int x)
 50     {
 51         rear++;
 52         q[rear]=x;
 53         size++;
 54     }
 55     int Getsize()
 56     {
 57         return size;
 58     }
 59 };
 60 queue mq;
 61 
 62 void BFS1(int s)
 63 {
 64     mq.Enqueue(s);
 65     flag[s]=1;
 66     while(mq.Getsize())
 67     {
 68         int now=mq.Dequeue();
 69         for(int i=begin[now];i!=-1;i=E[i].next)
 70          if(E[i].weight==-1&&flag[E[i].b]==0)
 71          {
 72             mq.Enqueue(E[i].b);
 73             flag[E[i].b]=1;
 74          }
 75     }
 76     for(int i=1;i<=n;i++)
 77     {
 78         for(int j=begin[i];j!=-1;j=E[j].next)
 79          if(E[j].weight==1&&flag[E[j].b]==0)
 80           getget[i]=0;
 81         if(flag[i]==0)
 82          getget[i]=0;
 83     }
 84 }
 85 
 86 int spfa(int s,int t)
 87 {
 88     mq.Enqueue(s);
 89     ifin[s]=1;
 90     dis[s]=0;
 91     while(mq.Getsize())
 92     {
 93         int now=mq.Dequeue();
 94         for(int i=begin[now];i!=-1;i=E[i].next)
 95          if(E[i].weight==1&&E[i].weight+dis[now]1)
 96          {
 97                 dis[E[i].b]=E[i].weight+dis[now];
 98                 if(ifin[E[i].b]==0)mq.Enqueue(E[i].b);
 99                 ifin[E[i].b]=1;
100          }
101         ifin[now]=0;
102     }
103     if(dis[t]==999999999)return -1;
104     else return dis[t];
105 }
106         
107 int main()
108 {
109     int a,b;
110     scanf("%d%d",&n,&m);
111     for(int i=0;i<=n;i++)
112      begin[i]=-1,dis[i]=999999999,getget[i]=1;
113     while(m--)
114     {
115         scanf("%d%d",&a,&b);
116         addedge(a,b);
117     }
118     scanf("%d%d",&a,&b);
119     BFS1(b);
120     printf("%d\n",spfa(a,b));
121     return 0;
122 }

描述

已知多项式方程:

a0+a1x+a2x2+...+anxn=0">a0+a1x+a2x2+...+anxn=0a0+a1x+a2x2+...+anxn=0

求这个方程在[1, m]内的整数解(n 和 m 均为正整数)。

格式

输入格式

输入共 n+2 行。

第一行包含 2 个整数 n、m,每两个整数之间用一个空格隔开。

接下来的 n+1 行每行包含一个整数,依次为a0,a1,a2,...,an">a0,a1,a2,...,ana0,a1,a2,...,an

输出格式

第一行输出方程在[1, m]内的整数解的个数。

接下来每行一个整数,按照从小到大的顺序依次输出方程在[1, m]内的一个整数解。

样例1

样例输入1[复制]

 
2 10
1
-2
1

样例输出1[复制]

 
1
1

样例2

样例输入2[复制]

 
2 10
2
-3
1

样例输出2[复制]

 
2
1
2

样例3

样例输入3[复制]

 
2 10
1
3
2

样例输出3[复制]

 
0

限制

对于 30%的数据,0 < n ≤ 2, |ai|">|ai||ai| ≤ 100,an">anan ≠ 0, m ≤ 100;

对于 50%的数据,0 < n ≤ 100, |ai|">|ai||ai|10100">1010010100an">anan ≠ 0,m ≤ 100;

对于 70%的数据,0 < n ≤ 100, |ai|">|ai||ai|1010000">10100001010000an">anan ≠ 0,m ≤ 10000;

对于 100%的数据,0 < n ≤ 100, |ai|">|ai||ai|1010000">10100001010000an">anan ≠ 0,m ≤ 1000000。

秦九昭算法依赖选择的质数可以的一定包括100的分

 1 #include
 2 #include
 3 #include
 4 using namespace std;
 5 int pr[20]={0,20011,20021,20023,20029,20047,20051,20063,20071,20089,20101,20107,20113,20117,20123,20129,20143,20147,20149,20161};
 6 int a[20][105],b[20][30005],ans[1000005];
 7 int n,m,count;
 8 
 9 void read(int x)
10 {
11     bool fl = 1;
12     char c = getchar();
13 
14     for(; (c < '0' || c > '9') ; c = getchar())
15         if(c == '-')
16             fl = 0;
17 
18     int ret[20];
19     for(int i = 1 ; i <= 19 ; i++) 
20         ret[i] = 0;
21 
22     for(; (c >= '0' && c <= '9') ; c = getchar())
23         for(int i = 1 ; i <= 19 ; i++)
24             ret[i] = (ret[i] * 10 + c - '0') % pr[i];
25 
26     for(int i = 1 ; i <= 19 ; i++)
27         a[i][x] = fl ? ret[i] : pr[i] - ret[i];
28 }
29 
30 void does(int x,int y)
31 {
32     int ans=0;
33     for(int i=n;i>=1;i--)
34      ans=(ans+a[x][i])*y%pr[x];
35     ans+=a[x][0];
36     ans%=pr[x];
37     if(ans==0)
38      b[x][y]=1;
39 }
40 
41 int main()
42 {
43     scanf("%d%d",&n,&m);
44     for(int i=0;i<=n;i++)
45      read(i);
46     for(int i=1;i<20;i++)
47      for(int j=1;j)
48       does(i,j);
49     for(int i=1;i<=m;i++)
50     {
51         int mark=1;
52         for(int j=1;j<20;j++)
53          if(b[j][i%pr[j]]==0)
54          {
55              mark=0;
56              break;
57          }
58         if(mark==1)
59          ans[i]=1,count++;
60     }
61     printf("%d\n",count);
62     for(int i=0;i<=m;i++)
63      if(ans[i]==1)
64       printf("%d\n",i);
65     return 0;
66 }