matrix_last_acm_3

the first CCPC   password 123

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=97380#problem/A

题意:给两个2*2的矩阵,问是否完全相同,其中一个矩阵可以旋转任意次90度。

解法:转4次都测一下是否相同。

 1 //#define debug
 2 //#define txtout
 3 #include<cstdio>
 4 #include<cstdlib>
 5 #include<cstring>
 6 #include<cmath>
 7 #include<cctype>
 8 #include<ctime>
 9 #include<iostream>
10 #include<algorithm>
11 #include<vector>
12 #include<queue>
13 #include<stack>
14 #include<map>
15 #include<set>
16 #define mt(a,b) memset(a,b,sizeof(a))
17 using namespace std;
18 typedef long long LL;
19 const double eps=1e-8;
20 const double pi=acos(-1.0);
21 const int inf=0x3f3f3f3f;
22 const int M=1e2+10;
23 int a[M];
24 int b[M];
25 char str[][16]={"POSSIBLE","IMPOSSIBLE"};
26 bool judge(int d){
27     for(int i=0;i<4;i++){
28         if(a[i]!=b[(i+d)%4]) return false;
29     }
30     return true;
31 }
32 int solve(){
33     for(int i=0;i<4;i++){
34         if(judge(i)) return 0;
35     }
36     return 1;
37 }
38 int main(){
39     #ifdef txtout
40     freopen("in.txt","r",stdin);
41     freopen("out.txt","w",stdout);
42     #endif
43     int t;
44     while(~scanf("%d",&t)){
45         int cas=1;
46         while(t--){
47             scanf("%d%d%d%d",&a[0],&a[1],&a[3],&a[2]);
48             scanf("%d%d%d%d",&b[0],&b[1],&b[3],&b[2]);
49             printf("Case #%d: %s
",cas++,str[solve()]);
50         }
51     }
52     return 0;
53 }
View Code

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=97380#problem/D

题意:将n个长度为a,价值为v的木棍放在长度为L的桌面上,其中两端的木棍只要保证中心在桌面上就行,问能得到的最大价值。

解法:就是01背包问题,只是其中有两个物体的花费可以除以2.下面用了一种非常不优美,但是比较好理解的dp,卡过。把所有长度*2避免浮点数。然后dp【i】【j】【k】表示前i个物品花费了j的长度有k个是减半的最大价值。i需要滚动。

 1 //#define debug
 2 //#define txtout
 3 #include<cstdio>
 4 #include<cstdlib>
 5 #include<cstring>
 6 #include<cmath>
 7 #include<cctype>
 8 #include<ctime>
 9 #include<iostream>
10 #include<algorithm>
11 #include<vector>
12 #include<queue>
13 #include<stack>
14 #include<map>
15 #include<set>
16 #define mt(a,b) memset(a,b,sizeof(a))
17 using namespace std;
18 typedef long long LL;
19 const double eps=1e-8;
20 const double pi=acos(-1.0);
21 const int inf=0x3f3f3f3f;
22 const int M=1e3+10;
23 int a[M];
24 int v[M];
25 int n,L;
26 LL dp[2][M<<2][3];
27 void init(int now){
28     for(int i=0;i<=L;i++){
29         for(int j=0;j<3;j++){
30             dp[now][i][j]=-1;
31         }
32     }
33 }
34 void Copy(int now,int pre){
35     for(int i=0;i<=L;i++){
36         for(int j=0;j<3;j++){
37             dp[now][i][j]=dp[pre][i][j];
38         }
39     }
40 }
41 void update(int now,int i,int j,LL value){
42     dp[now][i][j]=max(dp[now][i][j],value);
43 }
44 LL solve(){
45     L<<=1;
46     for(int i=1;i<=n;i++){
47         a[i]<<=1;
48     }
49     init(0);
50     dp[0][0][0]=0;
51     int now=0;
52     int pre=1;
53     for(int i=1;i<=n;i++){
54         now^=1;
55         pre^=1;
56         Copy(now,pre);
57         for(int j=0;j<=L;j++){
58             for(int k=0;k<3;k++){
59                 LL &ans=dp[pre][j][k];
60                 if(ans==-1) continue;
61                 if(j+a[i]<=L){
62                     update(now,j+a[i],k,ans+v[i]);
63                 }
64                 if(k<2&&j+(a[i]>>1)<=L){
65                     update(now,j+(a[i]>>1),k+1,ans+v[i]);
66                 }
67             }
68         }
69     }
70     LL res=0;
71     for(int i=1;i<=n;i++){
72         res=max(res,0LL+v[i]);
73     }
74     for(int i=0;i<=L;i++){
75         for(int j=0;j<3;j++){
76             res=max(res,dp[now][i][j]);
77         }
78     }
79     return res;
80 }
81 int main(){
82     #ifdef txtout
83     freopen("in.txt","r",stdin);
84     freopen("out.txt","w",stdout);
85     #endif
86     int t;
87     while(~scanf("%d",&t)){
88         int cas=1;
89         while(t--){
90             scanf("%d%d",&n,&L);
91             for(int i=1;i<=n;i++){
92                 scanf("%d%d",&a[i],&v[i]);
93             }
94             printf("Case #%d: %lld
",cas++,solve());
95         }
96     }
97     return 0;
98 }
View Code

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=97380#problem/G

题意:给一盘围棋,XO分别是黑白棋,点是空的,问再放一个X能否杀掉一部分o,能杀就是o的连通块边缘没有空。

解法1:dfs出o的连通块,统计与之相邻的空格有几个,如果只有一个就可以杀。

 1 //#define debug
 2 //#define txtout
 3 #include<cstdio>
 4 #include<cstdlib>
 5 #include<cstring>
 6 #include<cmath>
 7 #include<cctype>
 8 #include<ctime>
 9 #include<iostream>
10 #include<algorithm>
11 #include<vector>
12 #include<queue>
13 #include<stack>
14 #include<map>
15 #include<set>
16 #define mt(a,b) memset(a,b,sizeof(a))
17 using namespace std;
18 typedef long long LL;
19 const double eps=1e-8;
20 const double pi=acos(-1.0);
21 const int inf=0x3f3f3f3f;
22 const int M=1e2+10;
23 char a[M][M];
24 char str[][32]={"Can kill in one move!!!","Can not kill in one move!!!"};
25 bool vis[M][M];
26 bool sum[M][M];
27 int dx[]={0,0,1,-1};
28 int dy[]={1,-1,0,0};
29 void init(bool v[M][M]){
30     for(int i=0;i<9;i++){
31         for(int j=0;j<9;j++){
32             v[i][j]=false;
33         }
34     }
35 }
36 bool inside(int x,int y){
37     return x>=0&&x<9&&y>=0&&y<9;
38 }
39 void dfs(int x,int y){
40     vis[x][y]=true;
41     for(int i=0;i<4;i++){
42         int tx=x+dx[i];
43         int ty=y+dy[i];
44         if(!inside(tx,ty)) continue;
45         if(vis[tx][ty]) continue;
46         if(a[tx][ty]=='x') continue;
47         if(a[tx][ty]=='.'){
48             sum[tx][ty]=true;
49             continue;
50         }
51         dfs(tx,ty);
52     }
53 }
54 bool can_kill(int sx,int sy){
55     init(sum);
56     dfs(sx,sy);
57     int res=0;
58     for(int i=0;i<9;i++){
59         for(int j=0;j<9;j++){
60             if(sum[i][j]){
61                 res++;
62                 if(res>1) return false;
63             }
64         }
65     }
66     return true;
67 }
68 int solve(){
69     init(vis);
70     for(int i=0;i<9;i++){
71         for(int j=0;j<9;j++){
72             if(vis[i][j]) continue;
73             if(a[i][j]!='o') continue;
74             if(can_kill(i,j)) return 0;
75         }
76     }
77     return 1;
78 }
79 int main(){
80     #ifdef txtout
81     freopen("in.txt","r",stdin);
82     freopen("out.txt","w",stdout);
83     #endif
84     int t;
85     while(~scanf("%d",&t)){
86         int cas=1;
87         while(t--){
88             for(int i=0;i<9;i++){
89                 scanf("%s",a[i]);
90             }
91             printf("Case #%d: %s
",cas++,str[solve()]);
92         }
93     }
94     return 0;
95 }
View Code

解法2:bfs出连通块,思路同上。

  1 //#define debug
  2 //#define txtout
  3 #include<cstdio>
  4 #include<cstdlib>
  5 #include<cstring>
  6 #include<cmath>
  7 #include<cctype>
  8 #include<ctime>
  9 #include<iostream>
 10 #include<algorithm>
 11 #include<vector>
 12 #include<queue>
 13 #include<stack>
 14 #include<map>
 15 #include<set>
 16 #define mt(a,b) memset(a,b,sizeof(a))
 17 using namespace std;
 18 typedef long long LL;
 19 const double eps=1e-8;
 20 const double pi=acos(-1.0);
 21 const int inf=0x3f3f3f3f;
 22 const int M=1e2+10;
 23 char a[M][M];
 24 char str[][32]={"Can kill in one move!!!","Can not kill in one move!!!"};
 25 bool vis[M][M];
 26 bool sum[M][M];
 27 int dx[]={0,0,1,-1};
 28 int dy[]={1,-1,0,0};
 29 struct Q{
 30     int x,y;
 31 }now,pre;
 32 queue<Q> q;
 33 void init(bool v[M][M]){
 34     for(int i=0;i<9;i++){
 35         for(int j=0;j<9;j++){
 36             v[i][j]=false;
 37         }
 38     }
 39 }
 40 bool inside(int x,int y){
 41     return x>=0&&x<9&&y>=0&&y<9;
 42 }
 43 void bfs(int x,int y){
 44     vis[x][y]=true;
 45     now.x=x;
 46     now.y=y;
 47     while(!q.empty()) q.pop();
 48     q.push(now);
 49     while(!q.empty()){
 50         pre=q.front();
 51         q.pop();
 52         for(int i=0;i<4;i++){
 53             int tx=pre.x+dx[i];
 54             int ty=pre.y+dy[i];
 55             if(!inside(tx,ty)) continue;
 56             if(vis[tx][ty]) continue;
 57             if(a[tx][ty]=='x') continue;
 58             if(a[tx][ty]=='.'){
 59                 sum[tx][ty]=true;
 60                 continue;
 61             }
 62             vis[tx][ty]=true;
 63             now.x=tx;
 64             now.y=ty;
 65             q.push(now);
 66         }
 67     }
 68 }
 69 bool can_kill(int sx,int sy){
 70     init(sum);
 71     bfs(sx,sy);
 72     int res=0;
 73     for(int i=0;i<9;i++){
 74         for(int j=0;j<9;j++){
 75             if(sum[i][j]){
 76                 res++;
 77                 if(res>1) return false;
 78             }
 79         }
 80     }
 81     return true;
 82 }
 83 int solve(){
 84     init(vis);
 85     for(int i=0;i<9;i++){
 86         for(int j=0;j<9;j++){
 87             if(vis[i][j]) continue;
 88             if(a[i][j]!='o') continue;
 89             if(can_kill(i,j)) return 0;
 90         }
 91     }
 92     return 1;
 93 }
 94 int main(){
 95     #ifdef txtout
 96     freopen("in.txt","r",stdin);
 97     freopen("out.txt","w",stdout);
 98     #endif
 99     int t;
100     while(~scanf("%d",&t)){
101         int cas=1;
102         while(t--){
103             for(int i=0;i<9;i++){
104                 scanf("%s",a[i]);
105             }
106             printf("Case #%d: %s
",cas++,str[solve()]);
107         }
108     }
109     return 0;
110 }
View Code

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=97380#problem/H

题意:给出4*4的矩阵,数字为1到4,*为未确定,给*赋值1到4,使得每行每列,四个角的2*2内都没有相同元素,保证唯一解。

解法1:把每一个位置可能的情况都存下set,每次出现只剩一个就说明该位置确定,然后将其所在行列块都删去这个数,直至推出答案。

 1 //#define debug
 2 //#define txtout
 3 #include<cstdio>
 4 #include<cstdlib>
 5 #include<cstring>
 6 #include<cmath>
 7 #include<cctype>
 8 #include<ctime>
 9 #include<iostream>
10 #include<algorithm>
11 #include<vector>
12 #include<queue>
13 #include<stack>
14 #include<map>
15 #include<set>
16 #define mt(a,b) memset(a,b,sizeof(a))
17 using namespace std;
18 typedef long long LL;
19 const double eps=1e-8;
20 const double pi=acos(-1.0);
21 const int inf=0x3f3f3f3f;
22 const int M=1e2+10;
23 char a[M][M];
24 int b[M][M];
25 int dx[]={0,0,1,1};
26 int dy[]={0,1,0,1};
27 set<int> s[M][M];
28 void init(){
29     for(int i=0;i<4;i++){
30         for(int j=0;j<4;j++){
31             s[i][j].clear();
32             if(a[i][j]=='*'){
33                 for(int k=1;k<=4;k++){
34                     s[i][j].insert(k);
35                 }
36             }
37             else{
38                 s[i][j].insert(a[i][j]-'0');
39             }
40         }
41     }
42 }
43 void Erase(int x,int y,int value){
44     for(int i=0;i<4;i++){
45         s[i][y].erase(value);
46         s[x][i].erase(value);
47     }
48     if(x&1) x--;
49     if(y&1) y--;
50     for(int i=0;i<4;i++){
51         int tx=x+dx[i];
52         int ty=y+dy[i];
53         s[tx][ty].erase(value);
54     }
55 }
56 void solve(){
57     init();
58     bool flag=true;
59     while(flag){
60         flag=false;
61         for(int i=0;i<4;i++){
62             for(int j=0;j<4;j++){
63                 if(s[i][j].size()==1){
64                     flag=true;
65                     b[i][j]=*s[i][j].begin();
66                     Erase(i,j,b[i][j]);
67                 }
68             }
69         }
70     }
71 }
72 int main(){
73     #ifdef txtout
74     freopen("in.txt","r",stdin);
75     freopen("out.txt","w",stdout);
76     #endif
77     int t;
78     while(~scanf("%d",&t)){
79         int cas=1;
80         while(t--){
81             for(int i=0;i<4;i++){
82                 scanf("%s",a[i]);
83             }
84             solve();
85             printf("Case #%d:
",cas++);
86             for(int i=0;i<4;i++){
87                 for(int j=0;j<4;j++){
88                     printf("%d",b[i][j]);
89                 }
90                 puts("");
91             }
92         }
93     }
94     return 0;
95 }
View Code

 解法2:dfs每一个位置的取值,暴力所有情况。

 1 //#define debug
 2 //#define txtout
 3 #include<cstdio>
 4 #include<cstdlib>
 5 #include<cstring>
 6 #include<cmath>
 7 #include<cctype>
 8 #include<ctime>
 9 #include<iostream>
10 #include<algorithm>
11 #include<vector>
12 #include<queue>
13 #include<stack>
14 #include<map>
15 #include<set>
16 #define mt(a,b) memset(a,b,sizeof(a))
17 using namespace std;
18 typedef long long LL;
19 const double eps=1e-8;
20 const double pi=acos(-1.0);
21 const int inf=0x3f3f3f3f;
22 const int M=1e2+10;
23 char a[M][M];
24 int b[M][M];
25 int dx[]={0,0,1,1};
26 int dy[]={0,1,0,1};
27 void init(){
28     for(int i=0;i<4;i++){
29         for(int j=0;j<4;j++){
30             b[i][j]=-1;
31             if(a[i][j]!='*'){
32                 b[i][j]=a[i][j]-'0';
33             }
34         }
35     }
36 }
37 bool same(int x,int y,int value){
38     for(int i=0;i<4;i++){
39         if(b[x][i]==value) return true;
40         if(b[i][y]==value) return true;
41     }
42     if(x&1) x--;
43     if(y&1) y--;
44     for(int i=0;i<4;i++){
45         int tx=x+dx[i];
46         int ty=y+dy[i];
47         if(b[tx][ty]==value) return true;
48     }
49     return false;
50 }
51 bool dfs(int x,int y){
52     if(x==4) return true;
53     if(y==4) return dfs(x+1,0);
54     if(b[x][y]!=-1) return dfs(x,y+1);
55     for(int i=1;i<=4;i++){
56         if(same(x,y,i)) continue;
57         b[x][y]=i;
58         if(dfs(x,y+1)) return true;
59         b[x][y]=-1;
60     }
61     return false;
62 }
63 void solve(){
64     init();
65     dfs(0,0);
66 }
67 int main(){
68     #ifdef txtout
69     freopen("in.txt","r",stdin);
70     freopen("out.txt","w",stdout);
71     #endif
72     int t;
73     while(~scanf("%d",&t)){
74         int cas=1;
75         while(t--){
76             for(int i=0;i<4;i++){
77                 scanf("%s",a[i]);
78             }
79             solve();
80             printf("Case #%d:
",cas++);
81             for(int i=0;i<4;i++){
82                 for(int j=0;j<4;j++){
83                     printf("%d",b[i][j]);
84                 }
85                 puts("");
86             }
87         }
88     }
89     return 0;
90 }
View Code

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=97380#problem/L

题意:给n种字母,问组成最短的回文串的长度。

解法:n*2-1。

 1 //#define debug
 2 //#define txtout
 3 #include<cstdio>
 4 #include<cstdlib>
 5 #include<cstring>
 6 #include<cmath>
 7 #include<cctype>
 8 #include<ctime>
 9 #include<iostream>
10 #include<algorithm>
11 #include<vector>
12 #include<queue>
13 #include<stack>
14 #include<map>
15 #include<set>
16 #define mt(a,b) memset(a,b,sizeof(a))
17 using namespace std;
18 typedef long long LL;
19 const double eps=1e-8;
20 const double pi=acos(-1.0);
21 const int inf=0x3f3f3f3f;
22 const int M=1e5+10;
23 int a[M];
24 int main(){
25     #ifdef txtout
26     freopen("in.txt","r",stdin);
27     freopen("out.txt","w",stdout);
28     #endif
29     int t,n;
30     while(~scanf("%d",&t)){
31         int cas=1;
32         while(t--){
33             scanf("%d",&n);
34             printf("Case #%d: %d
",cas++,n*2-1);
35         }
36     }
37     return 0;
38 }
View Code

end

原文地址:https://www.cnblogs.com/gaolzzxin/p/4924506.html