第一题 细胞分裂 大意:

  还是细胞分裂的背景,经过x秒后,有很多细胞,每y个细胞会抱团,问剩下的细胞有多少个。对于100%,0≤x<2^233333,y 是3 到1000 之间(含两端)的质数。

解题:  本来觉得挺简单,果然有诈,数据这么大。我还看错了,以为是40%的x<2^64 可以不用高精度,结果是2^x,也就是(2^64)^64,额。然后觉得肯定要用高精度+快速幂。但听说只能过70,所以正解是费马小定理。讲数论的时候没有听懂,现在终于懂了。

    费马小定理:x^(b-1)%b=1  设整数p,p/(b-1)为整数,则x^(p/(b-1)*(b-1))%b=x^(b-1)%b=1; 所以:

    x^(p/(b-1)*(b-1)+p%(b-1))%b=x^(p%(b-1))%b,即x^p%b=x^(p%(b-1))%b

  我们可以把2^x%y的x预处理为较小的数。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<string>
 6 #define ll long long
 7 using namespace std;
 8 int x,y;
 9 ll ans=1;
10 char s[100005]; 
11 void smaller_x()
12 {
13     char c;
14     int len=strlen(s);
15     for (int i=0;i<len;i++)
16     {
17         c=s[i];
18         x=((c-'0')+(x<<1)+(x<<3))%(y-1);
19     }
20 }
21 int main(){
22     freopen("cell.in","r",stdin);
23     freopen("cell.out","w",stdout);
24     scanf("%s%d",s,&y);
25     smaller_x();
26     for (int i=1;i<=x;i++)
27       ans=(ans*2)%y;
28     cout<<ans;
29     return 0;
30 } 

第二题:

通风管
【问题描述】
你只剩6 条管道,他们都是同一型号的弯管。
你必须在指定的空间内装一个管道。空间是一个长方体,所有的边的都是单
位长度的整倍数,可以想象为一个空间堆满了单位正方体。每个弯管占用恰好4
个单位的正方体,如下图1 所示。两个弯管不能重合在同一个单位正方体上。每
个弯管只有2 个口,它们在图形1 中以灰色显示。你可以把2 个弯管接成一根长
的管子,但是它们不得超过给定的空间。图2 表示了其中一种对接方式。你的任
务是接通入口和出口。入口和出口在给定空间的外表面上,和单位正方体对齐,
如图3 所示。为了减少开支,你必须用最少的弯管解决这个问题。

 

【输入文件】
输入文件为tube.in。
输入包含一行,为11 个用空格隔开的值。
前3 个是整数(xmax,ymax,zmax)表示给定长方体的长宽高。长方体内的每个
单位正方体用坐标(x,y,z)表示, 其中1≤x≤xmax, 1≤y≤ymax, 1≤z≤zmax。
xmax,ymax,zmax 均为正且不大于20。
接下来3 个整数,表示入口所在单位立方体的坐标。
接下来是2 个字符构成的字符串,表示进入的朝向。可能为以下的一种:+
x,-x,+y,-y,+z,-z。举例来说,如果为+y,代表进入的方向为y 轴正方向,所以入
口面向y 轴负方向。
接下来3 个整数,表示出口所在单位立方体的坐标。
最后是2 个字符构成的字符串,表示流出的朝向。可能为以下的一种:+
x,-x,+y,-y,+z,-z。举例来说,如果为+y,代表出去的方向为y 轴正方向,所以出
口面向y 轴正方向。(注意与上面的不同之处。)

【输出文件】
输出文件为tube.out。
输出一行,为接通管道,并且不超过指定空间,最少需要的弯管数。如果不
可能用6 个弯管完成,则输出Impossible。

解:

  我几乎用所有的时间在写这道题。。。第一次写长达200+行的代码,就是忘加一个剪枝了,于是T了两个点-_-。不过还是很有成就感,虽然总体上这次考试得的分数不高。我写的dfs,只用了一个增量数组,所以很多判断语句显得很冗长。草稿纸上画了好多图。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<algorithm>
  4 #include<cstring>
  5 using namespace std;
  6 const int zl[4][4]={{0,0,2,-2},{-2,2,0,0},{0,0,1,-1},{-1,1,0,0}};
  7 int x,y,z,st,en,ans=6;
  8 int stx,sty,stz,enx,eny,enz;
  9 bool can=false,vis[25][25][25];
 10 void init()
 11 {
 12     cin>>x>>y>>z>>stx>>sty>>stz;
 13     char c[5],c2[5];
 14     getchar();
 15     c[0]=getchar();
 16     c[1]=getchar();
 17     cin>>enx>>eny>>enz;
 18     getchar();
 19     c2[0]=getchar();
 20     c2[1]=getchar();
 21     if (c[0]=='+'){
 22         if (c[1]=='x') st=1;//left in
 23         else if(c[1]=='y') st=3;//front in
 24         else if (c[1]=='z') st=5;//down in
 25     }
 26     else {
 27         if (c[1]=='x') st=2;//right in
 28         else if(c[1]=='y') st=4;//back in
 29         else if (c[1]=='z') st=6;//up in
 30     }
 31     if (c2[0]=='+'){
 32         if (c2[1]=='x') en=1;
 33         else if(c2[1]=='y') en=3;
 34         else if (c2[1]=='z') en=5;
 35     }
 36     else {
 37         if (c2[1]=='x') en=2;
 38         else if(c2[1]=='y') en=4;
 39         else if (c2[1]=='z') en=6;
 40     }
 41 }
 42 int pd12(int j)
 43 {
 44     if (j==2) return 3;
 45     if (j==3) return 4;
 46     if (j==0) return 6;
 47     if (j==1) return 5;
 48 }
 49 int pd34(int j)
 50 {
 51     if (j==2) return 1;
 52     if (j==3) return 2;
 53     if (j==0) return 6;
 54     if (j==1) return 5;
 55 }
 56 int pd56(int j)
 57 {
 58     if (j==2) return 1;
 59     if (j==3) return 2;
 60     if (j==0) return 4;
 61     if (j==1) return 3;
 62 }
 63 void dfs(int dirin,int dirout,int xi,int yi,int zi,int used)
 64 {
 65     if (used>6) return ;
 66     if (dirin==dirout&&xi==enx&&yi==eny&&zi==enz){//到终点且方向相同 
 67             if (used<=ans) {
 68                 ans=used;
 69                 can=true;
 70             }
 71             return ;
 72     }
 73     if (used!=0&&dirin==3) yi+=1; 
 74     if (used!=0&&dirin==4) yi-=1;
 75     if (used!=0&&dirin==5) zi+=1;
 76     if (used!=0&&dirin==6) zi-=1;
 77     if (used!=0&&dirin==1) xi+=1; 
 78     if (used!=0&&dirin==2) xi-=1;
 79     if (dirin==1){
 80         if (xi>=x) return ;
 81         for (int i=1;i<=2;i++)
 82             for (int j=0;j<=3;j++)
 83               {
 84                   int dir=pd12(j);
 85                   if (i==1){
 86                       int xx=xi+1,yy=yi+zl[0][j],zz=zi+zl[1][j];
 87                       if (xx>=1&&xx<=x&&yy>=1&&yy<=y&&zz>=1&&zz<=z&&!vis[xx][yy][zz]){
 88                           vis[xx][yy][zz]=true;
 89                           dfs(dir,dirout,xx,yy,zz,used+1);
 90                           vis[xx][yy][zz]=false;
 91                       }
 92                           
 93                   }
 94                   else{
 95                       int xx=xi+2,yy=yi+zl[2][j],zz=zi+zl[3][j];
 96                       if (xx>=1&&xx<=x&&yy>=1&&yy<=y&&zz>=1&&zz<=z&&!vis[xx][yy][zz]){
 97                           vis[xx][yy][zz]=true;
 98                           dfs(dir,dirout,xx,yy,zz,used+1);
 99                           vis[xx][yy][zz]=false;
100                       }
101                   }
102               }
103     }
104     else if (dirin==2){
105         if (xi<=1) return ;
106         for (int i=1;i<=2;i++)
107             for (int j=0;j<=3;j++)
108               {
109                   int dir=pd12(j);
110                   if (i==1){
111                       int xx=xi-1,yy=yi+zl[0][j],zz=zi+zl[1][j];
112                       if (xx>=1&&xx<=x&&yy>=1&&yy<=y&&zz>=1&&zz<=z&&!vis[xx][yy][zz]){
113                           vis[xx][yy][zz]=true;
114                           dfs(dir,dirout,xx,yy,zz,used+1);
115                         vis[xx][yy][zz]=false;        
116                       }
117                   }
118                   else{
119                       int xx=xi-2,yy=yi+zl[2][j],zz=zi+zl[3][j];
120                       if (xx>=1&&xx<=x&&yy>=1&&yy<=y&&zz>=1&&zz<=z&&!vis[xx][yy][zz]){
121                           vis[xx][yy][zz]=true;
122                           dfs(dir,dirout,xx,yy,zz,used+1);
123                           vis[xx][yy][zz]=false;
124                       }    
125                   }
126               }
127     }
128     else if (dirin==3){
129         if (yi>=y) return ;
130         for (int i=1;i<=2;i++)
131             for (int j=0;j<=3;j++)
132               {
133                   int dir=pd34(j);
134                   if (i==1){
135                       int yy=yi+1,xx=xi+zl[0][j],zz=zi+zl[1][j];
136                       if (xx>=1&&xx<=x&&yy>=1&&yy<=y&&zz>=1&&zz<=z&&!vis[xx][yy][zz]){
137                           vis[xx][yy][zz]=true;
138                           dfs(dir,dirout,xx,yy,zz,used+1);      
139                         vis[xx][yy][zz]=false;            
140                       }
141                   }
142                   else{
143                       int yy=yi+2,xx=xi+zl[2][j],zz=zi+zl[3][j];
144                       if (xx>=1&&xx<=x&&yy>=1&&yy<=y&&zz>=1&&zz<=z&&!vis[xx][yy][zz]){
145                           vis[xx][yy][zz]=true;
146                             dfs(dir,dirout,xx,yy,zz,used+1);    
147                         vis[xx][yy][zz]=false;        
148                     }
149                   }
150               }
151     }
152     else if (dirin==4){
153         if (yi<=1) return ;
154         for (int i=1;i<=2;i++)
155             for (int j=0;j<=3;j++)
156               {
157                   int dir=pd34(j);
158                   if (i==1){
159                       int yy=yi-1,xx=xi+zl[0][j],zz=zi+zl[1][j];
160                       if (xx>=1&&xx<=x&&yy>=1&&yy<=y&&zz>=1&&zz<=z&&!vis[xx][yy][zz]){
161                           vis[xx][yy][zz]=true;
162                           dfs(dir,dirout,xx,yy,zz,used+1);
163                           vis[xx][yy][zz]=false;
164                       }
165                   }
166                   else{
167                       int yy=yi-2,xx=xi+zl[2][j],zz=zi+zl[3][j];
168                       if (xx>=1&&xx<=x&&yy>=1&&yy<=y&&zz>=1&&zz<=z&&!vis[xx][yy][zz]){
169                           vis[xx][yy][zz]=true;
170                            dfs(dir,dirout,xx,yy,zz,used+1); 
171                            vis[xx][yy][zz]=false;                
172                       }
173                   }
174               }
175     }
176     else if (dirin==5){
177         if (zi>=z) return ;
178         for (int i=1;i<=2;i++)
179             for (int j=0;j<=3;j++)
180               {
181                   int dir=pd56(j);
182                   if (i==1){
183                       int zz=zi+1,xx=xi+zl[0][j],yy=yi+zl[1][j];
184                       if (xx>=1&&xx<=x&&yy>=1&&yy<=y&&zz>=1&&zz<=z&&!vis[xx][yy][zz]){
185                           vis[xx][yy][zz]=true;
186                           dfs(dir,dirout,xx,yy,zz,used+1);        
187                           vis[xx][yy][zz]=false;
188                       }
189 
190                   }
191                   else{
192                       int zz=zi+2,xx=xi+zl[2][j],yy=yi+zl[3][j];
193                       if (xx>=1&&xx<=x&&yy>=1&&yy<=y&&zz>=1&&zz<=z&&!vis[xx][yy][zz]){
194                           vis[xx][yy][zz]=true;
195                           dfs(dir,dirout,xx,yy,zz,used+1);        
196                           vis[xx][yy][zz]=false;
197                       }
198 
199                   }
200               }
201     }
202     else if (dirin==6){
203         if(zi<=1) return ;
204         for (int i=1;i<=2;i++)
205             for (int j=0;j<=3;j++)
206               {
207                   int dir=pd56(j);
208                   if (i==1){
209                       int zz=zi-1,xx=xi+zl[0][j],yy=yi+zl[1][j];
210                       if (xx>=1&&xx<=x&&yy>=1&&yy<=y&&zz>=1&&zz<=z&&!vis[xx][yy][zz]){
211                           vis[xx][yy][zz]=true;
212                             dfs(dir,dirout,xx,yy,zz,used+1);        
213                             vis[xx][yy][zz]=false;
214                       }
215                   }
216                   else{
217                       int zz=zi-2,xx=xi+zl[2][j],yy=yi+zl[3][j];
218                       if (xx>=1&&xx<=x&&yy>=1&&yy<=y&&zz>=1&&zz<=z&&!vis[xx][yy][zz]){
219                           vis[xx][yy][zz]=true;
220                           dfs(dir,dirout,xx,yy,zz,used+1);
221                           vis[xx][yy][zz]=false;
222                       }
223                   }
224               }
225     }
226 }
227 int main()
228 {
229     freopen("tube.in","r",stdin);
230     freopen("tube.out","w",stdout);
231     init();
232     dfs(st,en,stx,sty,stz,0);
233     if (ans>6||can==false) cout<<"Impossible";
234     else cout<<ans;
235     return 0;
236 }
View Code

第三题:压路机

  一个矩阵图,每个节点和它的邻居(最多四个)由街道相连。每个街道恰好1 单位长。只要蒸汽压路机在经过某条街道之前或之后立即改变方向,它经过这条街道的实际耗时会变为估计值的2 倍。这种情况对于压路机从某个节点发动(比如Johnny 的起点)和到某个节点刹车(比如Johnny 的终点)也适用。

 

全部是9 的那条路看起来更加快捷。然而,因为加速和刹车的限制,每一条
边都需要2 倍的时间,这使得总时间达到108。由10 组成的路径更快,因为Johnny
可以在其中的两条路径上全速通过,即总用时100。

 

解:

  写一个bfs。数组用一个维方向,两个数组,一个是直走后,一个是转弯后,遍历所有情况,找最小。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<string>
 6 #include<queue>
 7 #define maxn 105
 8 #define M 12345678
 9 using namespace std;
10 int R,C,ri,ci,rj,cj;
11 int mp[maxn][maxn][4],zhi[maxn][maxn][4],zhuan[maxn][maxn];//0 left,1 right,2 up,3 down
12 const int zl[2][4]={{0,0,-1,1},{-1,1,0,0}};
13 struct pp{
14     int x,y;
15 };
16 bool vis[maxn][maxn];
17 queue<pp> q;
18 void init()
19 {
20     cin>>R>>C>>ri>>ci>>rj>>cj;
21     for (int i=1;i<=R;i++)
22     {
23         for (int j=1;j<=C-1;j++)
24         {
25             scanf("%d",&mp[i][j][1]);
26             if (mp[i][j][1]==0) mp[i][j][1]=M;
27             mp[i][j+1][0]=mp[i][j][1];
28         }
29         if (i<R)
30           for (int j=1;j<=C;j++)
31           {
32               scanf("%d",&mp[i][j][3]);
33               if (mp[i][j][3]==0) mp[i][j][3]=M;
34               mp[i+1][j][2]=mp[i][j][3];
35           }
36     }
37     for(int i=1;i<=R;i++)
38         for(int j=1;j<=C;j++)
39         {
40             for(int k=0;k<=3;k++)
41             zhi[i][j][k]=zhi[i][j][k]=M;
42             zhuan[i][j]=M;
43         }
44     for (int i=0;i<4;i++)
45       zhi[ri][ci][i]=0;
46     zhuan[ri][ci]=0;
47 }
48 void bfs()
49 {
50     pp st;
51     st.x=ri;st.y=ci;
52     q.push(st);
53     vis[st.x][st.y]=true;
54     while (!q.empty()){
55         pp suf=q.front();
56         q.pop();vis[suf.x][suf.y]=false;
57         for (int i=0;i<=3;i++)
58         {
59             pp cur;
60             cur.x=suf.x+zl[0][i];cur.y=suf.y+zl[1][i];
61             if (cur.x<=0||cur.x>R) continue;
62             if (cur.y<=0||cur.y>C) continue;
63             int last_dir=i^1;
64             int now=zhi[suf.x][suf.y][last_dir]+mp[suf.x][suf.y][i];
65             if ((cur.x!=rj||cur.y!=cj)&&(suf.x!=ri||suf.y!=ci))//起点,终点要加、减速 
66             {
67                 if (now<zhi[cur.x][cur.y][last_dir]){
68                     zhi[cur.x][cur.y][last_dir]=now;
69                     vis[cur.x][cur.y]=true;q.push(cur);
70                 } 
71             }
72             now=min(zhuan[suf.x][suf.y],zhi[suf.x][suf.y][last_dir])+mp[suf.x][suf.y][i]*2;
73             if (now<zhi[cur.x][cur.y][last_dir]){
74                 zhi[cur.x][cur.y][last_dir]=now;
75                 vis[cur.x][cur.y]=true;q.push(cur);
76             }
77             if (now<zhuan[cur.x][cur.y]){
78                 zhuan[cur.x][cur.y]=now;
79                 vis[cur.x][cur.y]=true;q.push(cur);
80             }
81         }
82     }
83 }
84 int main()
85 {
86     freopen("roller.in","r",stdin);
87     freopen("roller.out","w",stdout);
88     init();
89     bfs();
90     int ans=M;
91     for (int i=0;i<=3;i++)
92       ans=min(ans,zhi[rj][cj][i]);
93     ans=min(zhuan[rj][cj],ans);
94     if (ans==M) cout<<"Impossible";
95     else cout<<ans;
96     return 0;
97 }

 

 posted on 2016-11-06 19:50  qzgxlx  阅读(162)  评论(0编辑  收藏  举报