codeforces CF475 ABC 题解

Bayan 2015 Contest Warm Up

http://codeforces.com/contest/475

 

A - Bayan Bus

B - Strongly Connected City

C - Kamal-ol-molk's Painting

 

A. Bayan Bus

题意:输入人数k,输出一辆公交车!优先坐最后,同一排优先坐左边。

题解:暴力找地方坐啊!

 1 //#pragma comment(linker, "/STACK:102400000,102400000")
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<iostream>
 5 #include<cstring>
 6 #include<algorithm>
 7 #include<cmath>
 8 #include<map>
 9 #include<set>
10 #include<stack>
11 #include<queue>
12 using namespace std;
13 #define ll long long
14 #define usll unsigned ll
15 #define mz(array) memset(array, 0, sizeof(array))
16 #define mf1(array) memset(array, -1, sizeof(array))
17 #define minf(array) memset(array, 0x3f, sizeof(array))
18 #define REP(i,n) for(i=0;i<(n);i++)
19 #define FOR(i,x,n) for(i=(x);i<=(n);i++)
20 #define RD(x) scanf("%d",&x)
21 #define RD2(x,y) scanf("%d%d",&x,&y)
22 #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
23 #define WN(x) printf("%d\n",x);
24 #define RE  freopen("D.in","r",stdin)
25 #define WE  freopen("huzhi.txt","w",stdout)
26 #define mp make_pair
27 #define pb push_back
28 #define pf push_front
29 #define ppf pop_front
30 #define ppb pop_back
31 const double pi=acos(-1.0);
32 const double eps=1e-10;
33 
34 string s[10];
35 int k;
36 
37 int main(){
38     int i,j;
39     s[0]="+------------------------+";
40     s[1]="|#.#.#.#.#.#.#.#.#.#.#.|D|)";
41     s[2]="|#.#.#.#.#.#.#.#.#.#.#.|.|";
42     s[3]="|#.......................|";
43     s[4]="|#.#.#.#.#.#.#.#.#.#.#.|.|)";
44     s[5]="+------------------------+";
45     int len=s[0].length();
46     RD(k);
47     while(k--){
48         bool flag=0;
49         FOR(i,0,len-1){
50             FOR(j,0,5){
51                 if(s[j][i]=='#'){
52                     flag=1;
53                     s[j][i]='O';
54                     break;
55                 }
56             }
57             if(flag)break;
58         }
59     }
60     FOR(i,0,5){
61         cout<<s[i]<<endl;
62     }
63     return 0;
64 }
View Code

 

 

B. Strongly Connected City

题意:城市由一堆单行线组成,给出一堆单行线的方向,判断是否每个交点能到达每个交点。

题解:从每个点出发暴力dfs啊!每个点出发最多每个点走一次,O(n^2)!

 1 //#pragma comment(linker, "/STACK:102400000,102400000")
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<iostream>
 5 #include<cstring>
 6 #include<algorithm>
 7 #include<cmath>
 8 #include<map>
 9 #include<set>
10 #include<stack>
11 #include<queue>
12 using namespace std;
13 #define ll long long
14 #define usll unsigned ll
15 #define mz(array) memset(array, 0, sizeof(array))
16 #define mf1(array) memset(array, -1, sizeof(array))
17 #define minf(array) memset(array, 0x3f, sizeof(array))
18 #define REP(i,n) for(i=0;i<(n);i++)
19 #define FOR(i,x,n) for(i=(x);i<=(n);i++)
20 #define RD(x) scanf("%d",&x)
21 #define RD2(x,y) scanf("%d%d",&x,&y)
22 #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
23 #define WN(x) printf("%d\n",x);
24 #define RE  freopen("D.in","r",stdin)
25 #define WE  freopen("huzhi.txt","w",stdout)
26 #define mp make_pair
27 #define pb push_back
28 #define pf push_front
29 #define ppf pop_front
30 #define ppb pop_back
31 const double pi=acos(-1.0);
32 const double eps=1e-10;
33 
34 string s[2];
35 int n,m;
36 
37 bool f[22][22];
38 int cnt;
39 
40 void dfs(int x,int y){
41     if(x<0 || x>=n || y<0 || y>=m || f[x][y])return;
42     //printf("(%d,%d) ",x,y);
43     f[x][y]=1;
44     cnt++;
45     if(s[0][x]=='>')dfs(x,y+1);
46     else dfs(x,y-1);
47     if(s[1][y]=='v')dfs(x+1,y);
48     else dfs(x-1,y);
49 }
50 
51 bool farm(){
52     int i,j;
53     REP(i,n){
54         REP(j,m){
55             mz(f);
56             cnt=0;
57             dfs(i,j);
58             if(cnt!=m*n)return 0;
59         }
60     }
61     return 1;
62 }
63 
64 int main(){
65     int i,j;
66     RD2(n,m);
67     cin>>s[0]>>s[1];
68     //cout<<s[0]<<'!'<<s[1]<<'!';
69     if(farm())puts("YES");
70     else puts("NO");
71     return 0;
72 }
View Code

 

 

C. Kamal-ol-molk's Painting

题意:给出一个图,其中“X”是刷的,“.”是不能刷的。刷子是个矩形,刷的时候要从某个地方下笔,只能往右或者往下移动。问是否能用刷子刷出这个图,不能则输出-1,能则输出最小的刷子的面积。

题解:先找到最左上的X,当做起点。然后找两个轨迹:

优先往右其次往下,可以得到刷子右上角的轨迹。

优先往下其次往右,能得到刷子左下角的轨迹。

但这些轨迹的初始和结尾部分不是轨迹,真正是轨迹的只有中间部分。从哪里开始是轨迹,由刷子的形状决定。

有两种情况,一种是右上角的轨迹开始向下走的那一格,当做右上角的初始位置,左下角的初始位置暂定为起点,然后我们就开始两个轨迹同步动。

若两个轨迹的移动方向不同,则说明左下角的初始位置选得不对,将左下角轨迹的下标++,直到两种轨迹相同。(若++使得刷子面积变小,则说明到结尾处了,则不++,使其结束)

最后时刻,得到的左下角坐标和右上角坐标,就真正决定了刷子形状,检查一下轨迹中是否都符合这个形状,符合而且刷的格子数等于X的数量的话,就得到一种解。

 

上面说的这种是先找右上角起始位置,另一种是先找左下角的起始位置,为左下角的轨迹开始往右走的那一格。而右上角的初始位置暂定为起点。与上面说的类似,弄着弄着就得到另一种解。

上面这两种情况也可能只有一种有解或者都没解。

最后有解的话输出面积小的那个面积,没解则输出-1。

 

(总体来说特别难搞,我是结束之后再交才A的……)

代码:

  1 //#pragma comment(linker, "/STACK:102400000,102400000")
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<iostream>
  5 #include<cstring>
  6 #include<algorithm>
  7 #include<cmath>
  8 #include<map>
  9 #include<set>
 10 #include<stack>
 11 #include<queue>
 12 using namespace std;
 13 #define ll long long
 14 #define usll unsigned ll
 15 #define mz(array) memset(array, 0, sizeof(array))
 16 #define mf1(array) memset(array, -1, sizeof(array))
 17 #define minf(array) memset(array, 0x3f, sizeof(array))
 18 #define REP(i,n) for(i=0;i<(n);i++)
 19 #define FOR(i,x,n) for(i=(x);i<=(n);i++)
 20 #define RD(x) scanf("%d",&x)
 21 #define RD2(x,y) scanf("%d%d",&x,&y)
 22 #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
 23 #define WN(x) printf("%d\n",x);
 24 #define RE  freopen("D.in","r",stdin)
 25 #define WE  freopen("huzhi.txt","w",stdout)
 26 #define mp make_pair
 27 #define pb push_back
 28 #define pf push_front
 29 #define ppf pop_front
 30 #define ppb pop_back
 31 const double pi=acos(-1.0);
 32 const double eps=1e-10;
 33 
 34 pair<int,int> operator -(pair<int,int>x,pair<int,int>y) {
 35     return mp(x.first-y.first,x.second-y.second);
 36 }
 37 
 38 int n,m;
 39 char a[1111][1111];
 40 
 41 int cnt;
 42 bool b[1111][1111];
 43 
 44 inline bool in(const int &x,const int &y) {
 45     return x>=0 && x<n && y>=0 && y<m;
 46 }
 47 
 48 inline bool can(const int &x,const int &y) {
 49     return (in(x,y)&&a[x][y]=='X');
 50 }
 51 
 52 inline int mj(pair<int,int>x , pair<int,int>y) {
 53     return (abs(x.first-y.first)+1) * (abs(x.second-y.second)+1);
 54 }
 55 
 56 vector<pair<int,int> > v[4];///右上角,左下角,右上角,左下角
 57 int sz[4];
 58 
 59 int farm() {
 60     if(cnt==1)return 1;
 61     int i,j;
 62 //    REP(i,n){
 63 //        REP(j,m){
 64 //            printf("%c",a[i][j]);
 65 //        }
 66 //        puts("");
 67 //    }
 68     REP(i,n) {
 69         REP(j,m) {
 70             if(a[i][j]=='X')break;
 71         }
 72         if(a[i][j]=='X')break;
 73     }
 74     int sx=i,sy=j;
 75     int x=sx,y=sy;
 76     //printf("%d,%d\n",sx,sy);
 77     v[0].clear();
 78     while(1) {
 79         v[0].pb(mp(x,y));
 80         int c1=can(x+1,y),c2=can(x,y+1),c3=can(x+1,y+1);
 81         //printf("(%d,%d) %d,%d,%d %c\n",x,y,c1,c2,c3,a[x+1][y]);
 82         if(c1&&c2&&!c3)return -1;
 83         if(!c1 && !c2)break;
 84         if(c2)y++;
 85         else if(c1)x++;
 86     }
 87     x=sx;
 88     y=sy;
 89     v[1].clear();
 90     while(1) {
 91         //printf("[%d,%d]\n",x,y);
 92         v[1].pb(mp(x,y));
 93         int c1=can(x+1,y),c2=can(x,y+1),c3=can(x+1,y+1);
 94         if(c1&&c2&&!c3)return -1;
 95         if(!c1 && !c2)break;
 96         if(c1)x++;
 97         else if(c2)y++;
 98     }
 99     if(v[0].back()!=v[1].back())return -1;
100     int ex=v[0].back().first,ey=v[0].back().second;
101 
102     x=ex;
103     y=ey;
104     v[2].clear();
105     while(1) {
106         //printf("[%d,%d]\n",x,y);
107         v[2].pb(mp(x,y));
108         int c1=can(x-1,y),c2=can(x,y-1),c3=can(x-1,y-1);
109         if(c1&&c2&&!c3)return -1;
110         if(!c1 && !c2)break;
111         if(c1)x--;
112         else if(c2)y--;
113     }
114 
115     x=ex;
116     y=ey;
117     v[3].clear();
118     while(1) {
119         //printf("[%d,%d]\n",x,y);
120         v[3].pb(mp(x,y));
121         int c1=can(x-1,y),c2=can(x,y-1),c3=can(x-1,y-1);
122         if(c1&&c2&&!c3)return -1;
123         if(!c1 && !c2)break;
124         if(c2)y--;
125         else if(c1)x--;
126     }
127     //printf("WOW!\n");
128     if(v[0].size()!=v[2].size() || v[1].size()!=v[3].size())return -1;
129     REP(i,4)sz[i]=v[i].size();
130     int t=sz[2]-1;
131     REP(i,sz[0]) {
132         if(v[0][i]!=v[2][t-i])return -1;
133     }
134     t=sz[3]-1;
135     REP(i,sz[1]) {
136         if(v[1][i]!=v[3][t-i])return -1;
137     }
138 
139     //printf("WA!");
140 
141     t=0;
142     while(t<sz[0]) {
143         if(t+1<sz[0] && v[0][t+1].first!=v[0][t].first)break;
144         t++;
145     }
146     int st=t;
147     int t2=0;
148     pair<int,int>cha=v[0][t]-v[1][t2];
149     while(t<sz[0] && t2<sz[1] && v[0][t]-v[1][t2] == cha) {
150         while(t2<sz[1] && t<sz[0]) {
151             if(t2+1<sz[1] && t+1<sz[0] && (v[1][t2+1]-v[1][t2]!=v[0][t+1]-v[0][t])
152                     && mj(v[0][t],v[1][t2+1]) > mj(v[0][t],v[1][t2]))
153                 t2++;
154             else break;
155         }
156         cha=v[0][t]-v[1][t2];
157         //printf("%d,%d %d,%d\n",v[0][t].first,v[0][t].second,v[1][t2].first,v[1][t2].second);
158         t++;
159         t2++;
160     }
161 
162     mz(b);
163     bool fail=0;
164     int cnt2=0;
165     t--,t2--;
166     while(t>=st) {
167         if(cha!=v[0][t]-v[1][t2]){
168                 //printf("cha!%d,%d %d,%d\n",v[0][t].first,v[0][t].second,v[1][t2].first,v[1][t2].second);
169                 fail=1;break;}
170         int rx=v[1][t2].first , lx=v[0][t].first;
171         int ry=v[0][t].second , ly=v[1][t2].second;
172         FOR(i,lx,rx) {
173             FOR(j,ly,ry) {
174                 if(a[i][j]!='X') {
175                     fail=1;
176                     break;
177                 }
178                 if(b[i][j])continue;
179                 b[i][j]=1;
180                 cnt2++;
181             }
182             if(fail)break;
183         }
184         if(fail)break;
185         t--;
186         t2--;
187     }
188     vector<int>re;
189     //printf("%d %d %d\n",fail,cnt2,cnt);
190     if(!fail && cnt2==cnt) {
191         //printf("!1\n");
192         re.pb((abs(cha.first)+1)*(abs(cha.second)+1));
193     }
194 ///上面那段复制过来改的!要错很可能是这里错
195     t=0;
196     while(t<sz[1]) {
197         if(t+1<sz[1] && v[1][t+1].second!=v[1][t].second)break;
198         t++;
199     }
200     st=t;
201     t2=0;
202     cha=v[0][t2]-v[1][t];
203     while(t<sz[1] && t2<sz[0] && v[0][t2]-v[1][t] == cha) {
204         while(t<sz[1] && t2<sz[0]) {
205             if(t2+1<sz[0] && t+1<sz[1] && (v[1][t+1]-v[1][t]!=v[0][t2+1]-v[0][t2])
206                     && mj(v[0][t2+1],v[1][t]) > mj(v[0][t2],v[1][t]))
207                 t2++;
208             else break;
209         }
210         //printf("[%d,%d] [%d,%d]\n",v[0][t2].first,v[0][t2].second,v[1][t].first,v[1][t].second);
211         cha=v[0][t2]-v[1][t];
212         t++;
213         t2++;
214     }
215     mz(b);
216     cnt2=0;
217     fail=0;
218     t--,t2--;
219     while(t>=st){
220         if(v[0][t2]-v[1][t] != cha){fail=1;break;}
221         int rx=v[1][t].first , lx=v[0][t2].first;
222         int ry=v[0][t2].second , ly=v[1][t].second;
223         FOR(i,lx,rx) {
224             FOR(j,ly,ry) {
225                 if(a[i][j]!='X') {
226                     fail=1;
227                     break;
228                 }
229                 if(b[i][j])continue;
230                 b[i][j]=1;
231                 cnt2++;
232             }
233             if(fail)break;
234         }
235         if(fail)break;
236         t--;
237         t2--;
238     }
239 
240     if(!fail && cnt2==cnt) {
241        // printf("!2\n");
242         re.pb((abs(cha.first)+1)*(abs(cha.second)+1));
243     }
244     sort(re.begin(),re.end());
245     if(re.size()!=0)return re[0];
246     else return -1;
247 }
248 
249 int main() {
250     int i,j;
251     cnt=0;
252     RD2(n,m);
253     REP(i,n) {
254         REP(j,m) {
255             scanf(" %c",&a[i][j]);
256             if(a[i][j]=='X')cnt++;
257         }
258     }
259     printf("%d\n",farm());
260     return 0;
261 }
View Code

 

posted @ 2014-10-06 01:11  带鱼Yuiffy  阅读(368)  评论(0编辑  收藏  举报