第四周 8.9-8.15

8.9

滚回家。

8.10

终于补了多校6。1006。

补个BC。

HDU 5365 Run

暴力举正方形即可。

(死在正方形判定上。初中没学好。)

 1 # include <iostream>
 2 # include <cstdio>
 3 # include <cmath>
 4 using namespace std;
 5 
 6 struct node
 7 {
 8     int x,y;
 9 }p[21];
10 
11 bool judge(int i,int j,int k,int l)
12 {        
13     if(p[i].x+p[k].x!=p[j].x+p[l].x) return false;
14     if(p[i].y+p[k].y!=p[j].y+p[l].y) return false;
15     if((p[i].y-p[k].y)*(p[j].y-p[l].y)+(p[i].x-p[k].x)*(p[j].x-p[l].x)) return false;
16     if(2*(pow(p[i].x-p[j].x,2)+pow(p[i].y-p[j].y,2))!=pow(p[i].x-p[k].x,2)+pow(p[i].y-p[k].y,2)) return false;
17     return true;
18 }
19 
20 int main(void)
21 {
22     int n;
23     while(~scanf("%d",&n))
24     {
25         for(int i=1;i<=n;i++)
26             scanf("%d%d",&p[i].x,&p[i].y);
27         int ans=0;
28         for(int i=1;i<=n;i++)
29         {
30             for(int j=1;j<=n;j++)
31             {
32                 if(j==i) continue;
33                 for(int k=1;k<=n;k++)
34                 {
35                     if(k==i||k==j) continue;
36                     for(int l=1;l<=n;l++)
37                     {
38                         if(l==i||l==j||l==k) continue;
39                         if(judge(i,j,k,l)) ans++;
40                     }
41                 }
42             }
43         }
44         ans/=8;
45         printf("%d
",ans);
46     }
47     return 0;
48 }
Aguin

下午陕多校。心累。不补!

8.11

切菜。

POJ 1331 棋盘问题

八皇后简单版。

 1 # include <iostream>
 2 # include <cstdio>
 3 # include <cstring>
 4 using namespace std;
 5 int n,k,map[9][9],col[9],ans;
 6 
 7 void dfs(int r,int rem)
 8 {
 9     if(rem==0) {ans++; return;}
10     if(r>n) return;
11     for(int i=1;i<=n;i++)
12     {
13         if(!col[i]&&!map[r][i])
14         {
15             col[i]=1;
16             dfs(r+1,rem-1);
17             col[i]=0;
18         }
19     }
20     if(r<n) dfs(r+1,rem);
21     return;
22 }
23 
24 int main(void)
25 {
26     while(~scanf("%d%d",&n,&k))
27     {
28         if(n==-1) break;
29         for(int i=1;i<=n;i++)
30         {
31             char s[10];
32             scanf("%s",s+1);
33             for(int j=1;j<=n;j++)
34                 map[i][j]=s[j]=='.'?1:0;
35         }
36         ans=0;
37         dfs(1,k);
38         printf("%d
",ans);
39     }
40     return 0;
41 }
Aguin

POJ 2251 Dungeon Master

拯救拉面女神。

 1 # include <iostream>
 2 # include <cstdio>
 3 # include <queue>
 4 using namespace std;
 5 char map[31][31][31];
 6 int L,R,C;
 7 int step[][3]={{0,0,1},{0,0,-1},{0,1,0},{0,-1,0},{1,0,0},{-1,0,0}};
 8 
 9 bool in(int l,int r,int c)
10 {
11     return l>0&&l<=L&&r>0&&r<=R&&c>0&&c<=C;
12 }
13 
14 struct node
15 {
16     int l,r,c;
17     friend bool operator ==(node a,node b)
18     {
19         return a.l==b.l&&a.r==b.r&&a.c==b.c;
20     }
21 }s,e;
22 typedef pair<node,int> pii;
23 
24 int main(void)
25 {
26     while(~scanf("%d%d%d",&L,&R,&C))
27     {
28         if(!L) break;
29         for(int i=1;i<=L;i++)
30         {
31             for(int j=1;j<=R;j++)
32             {
33                 char str[40];
34                 scanf("%s",str+1);
35                 for(int k=1;k<=C;k++)
36                 {
37                     map[i][j][k]=str[k];
38                     if(map[i][j][k]=='S') s={i,j,k};
39                     else if(map[i][j][k]=='E') e={i,j,k};
40                 }
41             }    
42         }
43         int ans=-1;
44         queue<pii> q;
45         q.push(pii(s,0));
46         while(!q.empty())
47         {
48             pii tem=q.front(); q.pop();
49             node p=tem.first;
50             int t=tem.second;
51             if(p==e) {ans=t; break;}
52             for(int i=0;i<6;i++)
53             {
54                 int x=p.l,y=p.r,z=p.c;
55                 x+=step[i][0];
56                 y+=step[i][1];
57                 z+=step[i][2];
58                 if(in(x,y,z)&&map[x][y][z]!='S'&&map[x][y][z]!='#')
59                 {
60                     node next={x,y,z};
61                     map[x][y][z]='#';
62                     q.push(pii(next,t+1));
63                 }
64             }
65         }
66         if(ans<0) printf("Trapped!
");
67         else printf("Escaped in %d minute(s).
",ans);
68     }
69     return 0;
70 }
Aguin

POJ 3278 Catch That Cow

水水BFS。

 1 # include <iostream>
 2 # include <cstdio>
 3 # include <cmath>
 4 # include <cstring>
 5 # include <queue>
 6 using namespace std;
 7 typedef pair<int,int> pii;
 8 queue <pii> q;
 9 bool vis[200000];
10 
11 int main(void)
12 {
13     int N,k;
14     while(~scanf("%d%d",&N,&k))
15     {
16         memset(vis,0,sizeof(vis));
17         while(!q.empty()) q.pop();
18         q.push(pii(N,0));
19         int ans=-1;
20         while(!q.empty())
21         {
22             pii tem=q.front(); q.pop();
23             int now=tem.first,t=tem.second;
24             if(now==k) {ans=t;break;}
25             if(fabs(2*now-k)<=fabs(now-k)&&!vis[2*now])
26             {
27                 vis[2*now]=1;
28                 q.push(pii(2*now,t+1));
29             }
30             if(now<k&&!vis[now+1])
31             {
32                 vis[now+1]=1;
33                 q.push(pii(now+1,t+1));    
34             } 
35             if(now>0&&!vis[now-1])
36             {
37                 vis[now-1]=1;
38                 q.push(pii(now-1,t+1));
39             } 
40         }
41         printf("%d
",ans);
42     }
43     return 0;
44 }
Aguin

下午多校。老样子。

补题。

8.12

补题。

POJ 3279 Fliptile

噫第一次写二进制枚举。好弱。

 1 # include <iostream>
 2 # include <cstdio>
 3 # include <cstring>
 4 # include <cmath>
 5 using namespace std;
 6 # define INF 2147483647
 7 int grid[16][16],tem[16][16],tem_ans[16][16],ans[16][16];
 8 int mov[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
 9 int M,N,Min;
10 
11 void ans_print(void)
12 {
13     for(int i=1;i<=M;i++)
14     {
15         for(int j=1;j<=N;j++)
16             printf("%d ",ans[i][j]);
17         printf("
");
18     }
19     return;
20 }
21 
22 bool in(int i,int j)
23 {
24     return i>0&&i<=M&&j>0&&j<=N;
25 }
26 
27 void judge(int x)
28 {
29     int t=0;
30     memcpy(tem,grid,sizeof(tem));
31     memset(tem_ans,0,sizeof(tem_ans));
32     for(int i=1;i<=x;i<<=1)
33     {
34         if(i&x)
35         {
36             t++;
37             int pos=log(i)/log(2)+1;
38             tem_ans[1][pos]=1;
39             if(in(1,pos-1)) tem[1][pos-1]=1-tem[1][pos-1];
40             if(in(1,pos+1)) tem[1][pos+1]=1-tem[1][pos+1];
41             tem[1][pos]=1-tem[1][pos];
42             tem[2][pos]=1-tem[2][pos];
43         }
44     }
45     for(int i=2;i<M;i++)
46     {
47         for(int j=1;j<=N;j++)
48         {
49             if(tem[i-1][j])
50             {
51                 t++;
52                 tem_ans[i][j]=1;
53                 tem[i][j]=1-tem[i][j];
54                 for(int k=0;k<4;k++)
55                     if(in(i+mov[k][0],j+mov[k][1]))
56                         tem[i+mov[k][0]][j+mov[k][1]]=1-tem[i+mov[k][0]][j+mov[k][1]];
57             }
58         }
59     }
60     for(int j=1;j<=N;j++)
61     {
62         if(in(M,j-1)&&tem[M][j-1]^tem[M-1][j]) return;
63         if(tem[M-1][j])
64         {
65             t++;
66             tem_ans[M][j]=1;
67             tem[M][j]=1-tem[M][j];
68             for(int k=0;k<4;k++)
69                 if(in(M+mov[k][0],j+mov[k][1]))
70                     tem[M+mov[k][0]][j+mov[k][1]]=1-tem[M+mov[k][0]][j+mov[k][1]];
71         }
72     }
73     if(tem[M][N]) return;
74     if(t<Min)
75     {
76         Min=t;
77         memcpy(ans,tem_ans,sizeof(ans));
78     }
79     return;
80 }
81 
82 int main(void)
83 {
84     scanf("%d%d",&M,&N);
85     for(int i=1;i<=M;i++)
86         for(int j=1;j<=N;j++)
87             scanf("%d",&grid[i][j]);
88     Min=INF;
89     for(int i=0;i<(1<<N);i++) judge(i);
90     if(Min<INF) ans_print();
91     else puts("IMPOSSIBLE");
92     return 0;
93 }
Aguin

POJ 1426 Find The Multiple

因为涉及数学我就不会了。于是最简单的dfs水果。

只要枚举01构成的数。不枚举n的倍数都是可以的。

 1 # include <iostream>
 2 # include <cstdio>
 3 using namespace std;
 4 typedef unsigned long long LL;
 5 const LL Max=(LL)1000000000000000000;
 6 LL ans;
 7 int n;
 8 
 9 bool dfs(LL num)
10 {
11     if(num%(LL)n==0) {ans=num;return true;}
12     if(num>Max) return false;
13     if(dfs(num*(LL)10)) return true;
14     if(dfs(num*(LL)10+(LL)1)) return true;
15     return false;
16 }
17 
18 int main(void)
19 {
20     while(~scanf("%d",&n))
21     {
22         if(!n) break;
23         dfs(1);
24         printf("%llu
",ans);    
25     }
26     return 0;
27 }
Aguin

8.13

POJ 3126 Prime Path

水水BFS。

 1 # include <iostream>
 2 # include <cstdio>
 3 # include <cstring>
 4 # include <queue>
 5 using namespace std;
 6 typedef pair<int,int> pii;
 7 int flag[10000],vis[10000];
 8 queue<pii> q;
 9 
10 int main(void)
11 {
12     for(int i=2;i<10000;i++)
13         for(int j=2*i;j<10000;j+=i)
14             flag[j]=1;
15     int T; cin>>T;
16     while(T--)
17     {
18         memset(vis,0,sizeof(vis));
19         int a,b;
20         scanf("%d%d",&a,&b);
21         while(!q.empty()) q.pop();
22         vis[a]=1;
23         q.push(pii(a,0));
24         int ans=-1;
25         while(!q.empty())
26         {
27             pii tem=q.front(); q.pop();
28             int now=tem.first,t=tem.second;
29             if(now==b) {ans=t;break;}
30             for(int i=0;i<=9;i++)
31             {
32                 int next=now/10*10+i;
33                 if(!flag[next]&&!vis[next])
34                     q.push(pii(next,t+1)),vis[next]=1;
35             }
36             for(int i=0;i<=9;i++)
37             {
38                 int p=now%10;
39                 int next=now/100*100+10*i+p;
40                 if(!flag[next]&&!vis[next])
41                     q.push(pii(next,t+1)),vis[next]=1;
42             }
43             for(int i=0;i<=9;i++)
44             {
45                 int p=now%100;
46                 int next=now/1000*1000+100*i+p;
47                 if(!flag[next]&&!vis[next])
48                     q.push(pii(next,t+1)),vis[next]=1;
49             }
50             for(int i=1;i<=9;i++)
51             {
52                 int next=now%1000+1000*i;
53                 if(!flag[next]&&!vis[next])
54                     q.push(pii(next,t+1)),vis[next]=1;
55             }
56         }
57         if(ans>=0) printf("%d
",ans);
58         else puts("Impossible");
59     }
60     return 0;
61 }
Aguin

POJ 3087 Shuffle'm Up

模拟洗牌。有循环就跳出。

 1 # include <iostream>
 2 # include <cstdio>
 3 # include <cstring>
 4 using namespace std;
 5 char a[300],b[300],ori[300],next[300],tar[300];
 6 
 7 int main(void)
 8 {
 9     int T;cin>>T;
10     for(int kase=1;kase<=T;kase++)
11     {
12         memset(ori,0,sizeof(ori));
13         memset(next,0,sizeof(next));
14         int len; scanf("%d",&len);
15         scanf("%s %s %s",a,b,tar);
16         for(int i=0;i<len;i++)
17         {
18             ori[i]=a[i];
19             ori[i+len]=b[i];
20         }
21         for(int i=0;i<len;i++)
22         {
23             next[2*i]=b[i];
24             next[2*i+1]=a[i];
25         }
26         int t=0,ans=-1;
27         while(strcmp(ori,next))
28         {
29             t++;
30             if(!strcmp(next,tar)) {ans=t;break;}
31             for(int i=0;i<len;i++)
32             {
33                 a[i]=next[i];
34                 b[i]=next[i+len];
35             }
36             for(int i=0;i<len;i++)
37             {
38                 next[2*i]=b[i];
39                 next[2*i+1]=a[i];
40             }
41         }
42         printf("%d %d
",kase,ans>0?ans:-1);
43     }
44     return 0;
45 }
Aguin

多校。low爆。

8.14

补题。看莫队。

8.15

初习莫队小结。

莫队算法用来解决一类无修改的离线区间询问问题。

能使用莫队的问题需要具有这样的特征。

即已知[L,R]的答案。可以推算出[L,R+1],[L-1,R]的答案。

推算这个的时间叫做转移时间。O(1)的最好。O(logN)的也可以尝试一下莫队。

莫队的核心在于对询问预先排序。使得相邻的询问的区间的L,R距离较小。从而通过步数较少的转移找到答案。

如何对询问排序呢?

容易看出。从区间[L1,R1]转移到[L2,R2]的代价是左右端点的曼哈顿距离之和乘上转移时间。

因此最早的方法是把询问看成平面点。再求最小曼哈顿距离树。

由于此方法较为复杂。现在较为常用的是一种方便的替代方法。

先将左端点分成sqrt(N)个块。块内按右端点排序。

分析下复杂度。

考虑右端点。

同一块中的询问处理完右端点最多转移N次。一共sqrt(N)块。所以右端点块内转移最多N*sqrt(N)次。

跨块时。跨一块最多转移N步。跨块最多进行sqrt(N)次。所以右端点跨块转移最多也是N*sqrt(N)次。

考虑左端点。

块内一次最多转移sqrt(N)步。一共M个询问。所以左端点块内转移最多M*sqrt(N)次。

跨一块最多转移2*sqrt(N)步。跨一块最多sqrt(N)次。所以左端点跨块最多转移2N次。

(跨多块的情况:例如一次跨k块。转移的步数为(k+1)*sqrt(N)显然比每次跨一块的2*k*sqrt(N)要少。)

所以当M与N同阶的时候。总的复杂度是N*sqrt(N)*转移时间。

这场多校做的少。花的时间多了。不搞了。

POJ 3414 Pots

BFS。因为要输出路径。所以用数组模拟保存前驱即可。

  1 # include <iostream>
  2 # include <cstdio>
  3 using namespace std;
  4 # define maxn 1000000
  5 int pre[maxn],vis[101][101];
  6 
  7 struct node
  8 {
  9     int l1,l2;
 10     int type,i,j;
 11 } op[maxn];
 12 
 13 void ans_print(int pos,int step)
 14 {
 15     if(pos!=1) ans_print(pre[pos],step+1);
 16     else printf("%d
",step);
 17     if(op[pos].type==1) printf("FILL(%d)
",op[pos].i);
 18     else if(op[pos].type==2) printf("DROP(%d)
",op[pos].i);
 19     else if(op[pos].type==3) printf("POUR(%d,%d)
",op[pos].i,op[pos].j);
 20     return;
 21 }
 22 
 23 int main(void)
 24 {
 25     int A,B,C;
 26     scanf("%d%d%d",&A,&B,&C);
 27     int l=1,r=1,ans=0;
 28     node tem,next;
 29     tem.l1=tem.l2=0;
 30     op[r]=tem;
 31     while(l<=r)
 32     {
 33         tem=op[l];
 34         int l1=tem.l1,l2=tem.l2;
 35         if(tem.l1==C||tem.l2==C) {ans=l; break;}
 36         if(!vis[A][l2])
 37         {
 38             next.type=1;
 39             next.i=1;
 40             next.l1=A;
 41             next.l2=l2;
 42             vis[A][l2]=1;
 43             op[++r]=next;
 44             pre[r]=l;
 45         }
 46         if(!vis[l1][B])
 47         {
 48             next.type=1;
 49             next.i=2;
 50             next.l1=l1;
 51             next.l2=B;
 52             vis[l1][B]=1;
 53             op[++r]=next;
 54             pre[r]=l;
 55         }
 56         if(!vis[0][l2])
 57         {
 58             next.type=2;
 59             next.i=1;
 60             next.l1=0;
 61             next.l2=l2;
 62             vis[0][l2]=1;
 63             op[++r]=next;
 64             pre[r]=l;
 65         }
 66         if(!vis[l1][0])
 67         {
 68             next.type=2;
 69             next.i=2;
 70             next.l1=l1;
 71             next.l2=0;
 72             vis[l1][0]=1;
 73             op[++r]=next;
 74             pre[r]=l;
 75         }
 76         if(l1+l2<=A&&!vis[l1+l2][0])
 77         {
 78             next.type=3;
 79             next.i=2;
 80             next.j=1;
 81             next.l1=l1+l2;
 82             next.l2=0;
 83             vis[l1+l2][0]=1;
 84             op[++r]=next;
 85             pre[r]=l;
 86         }
 87         if(l1+l2>A&&!vis[A][l1+l2-A])
 88         {
 89             next.type=3;
 90             next.i=2;
 91             next.j=1;
 92             next.l1=A;
 93             next.l2=l1+l2-A;
 94             vis[A][l1+l2-A]=1;
 95             op[++r]=next;
 96             pre[r]=l;
 97         }
 98         if(l1+l2<=B&&!vis[0][l1+l2])
 99         {
100             next.type=3;
101             next.i=1;
102             next.j=2;
103             next.l1=0;
104             next.l2=l1+l2;
105             vis[0][l1+l2]=1;
106             op[++r]=next;
107             pre[r]=l;
108         }
109         if(l1+l2>B&&!vis[l1+l2-B][B])
110         {
111             next.type=3;
112             next.i=1;
113             next.j=2;
114             next.l1=l1+l2-B;
115             next.l2=B;
116             vis[l1+l2-B][B]=1;
117             op[++r]=next;
118             pre[r]=l;
119         }
120         l++;
121     }
122     if(ans) ans_print(ans,0);
123     else puts("impossible");
124     return 0;
125 }
Aguin

FZU 2150 Fire Game

水水BFS。

 1 # include <iostream>
 2 # include <cstdio>
 3 # include <cstring>
 4 # include <algorithm>
 5 # include <queue>
 6 using namespace std;
 7 typedef pair<int,int> pii;
 8 typedef pair<pii,int> piii;
 9 int n,m;
10 int map[11][11],cpy[11][11];
11 int step[][2]={{0,1},{0,-1},{1,0},{-1,0}};
12 queue<piii> q;
13 
14 bool in(int i,int j)
15 {
16     return i>0&&i<=n&&j>0&&j<=m;
17 }
18 
19 int main(void)
20 {
21     int T; cin>>T;
22     for(int kase=1;kase<=T;kase++)
23     {
24         scanf("%d%d",&n,&m);
25         int tot=0,ans=-1;
26         for(int i=1;i<=n;i++)
27         {
28             char s[20];
29             scanf("%s",s+1);
30             for(int j=1;j<=m;j++)
31             {
32                 map[i][j]=(s[j]=='#')?1:0;
33                 tot+=map[i][j];
34             }
35         }
36         for(int i=1;i<=n;i++)
37             for(int j=1;j<=m;j++)
38                 for(int k=i;k<=n;k++)
39                     for(int l=(k==i)?j:1;l<=m;l++)
40                     {
41                         if(!map[i][j]||!map[k][l]) continue;
42                         int cnt=0,t;
43                         memcpy(cpy,map,sizeof(map));
44                         while(!q.empty()) q.pop();
45                         q.push(piii(pii(i,j),0));
46                         cpy[i][j]=0; cnt++;
47                         if(i!=k||j!=l)
48                         {
49                             q.push(piii(pii(k,l),0));
50                             cpy[k][l]=0;
51                             cnt++;
52                         }
53                         while(!q.empty())
54                         {
55                             piii tem=q.front();q.pop();
56                             int x=tem.first.first,y=tem.first.second;
57                             t=tem.second;
58                             for(int p=0;p<4;p++)
59                             {
60                                 int xx=x+step[p][0],yy=y+step[p][1];
61                                 if(!in(xx,yy)||!cpy[xx][yy]) continue;
62                                 cpy[xx][yy]=0; cnt++;
63                                 q.push(piii(pii(xx,yy),t+1));
64                             }
65                         }
66                         if(cnt==tot) ans=ans<0?t:min(ans,t);
67                     }
68         printf("Case %d: %d
",kase,ans);
69     }
70     return 0;
71 }
Aguin

晚上BC爆O。待补。

原文地址:https://www.cnblogs.com/Aguin/p/4714896.html