0%

近期题目

http://codeforces.com/problemset/problem/89/C 网状链表模拟...有点难写... 内存有可能开不下,要分类讨论一下内存...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
#include<bits/stdc++.h>
using namespace std;
int n,m;
char c[5010][5010]={};
short p[5001][550][4]={};
short q[5001][550][4]={};
short pi[550][5001][4]={};
short qi[550][5001][4]={};
void init()
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
int t=i-1;
while(t>=1)
{
if(c[t][j]=='.') t--;
else
{
p[i][j][0]=t;
break;
}
}
t=i+1;
while(t<=n)
{
if(c[t][j]=='.') t++;
else
{
p[i][j][1]=t;
break;
}
}
t=j-1;
while(t>=1)
{
if(c[i][t]=='.') t--;
else
{
p[i][j][2]=t;
break;
}
}
t=j+1;
while(t<=m)
{
if(c[i][t]=='.') t++;
else
{
p[i][j][3]=t;
break;
}
}
}
}
}
void pp()
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
for(int k=0;k<=3;k++)
{
q[i][j][k]=p[i][j][k];
}
}
}
}
int ff(int x,int y)
{
int ans=0;
pp();
while(1)
{
ans++;
int w;
if(c[x][y]=='U') w=q[x][y][0];
if(c[x][y]=='D') w=q[x][y][1];
if(c[x][y]=='L') w=q[x][y][2];
if(c[x][y]=='R') w=q[x][y][3];
if(w==0) break;
int e[4];
for(int i=0;i<=3;i++) e[i]=q[x][y][i];
if(e[0]!=0)
{
q[e[0]][y][1]=e[1];
}
if(e[1]!=0)
{
q[e[1]][y][0]=e[0];
}
if(e[2]!=0)
{
q[x][e[2]][3]=e[3];
}
if(e[3]!=0)
{
q[x][e[3]][2]=e[2];
}
if(c[x][y]=='U') x=e[0];
else if(c[x][y]=='D') x=e[1];
else if(c[x][y]=='L') y=e[2];
else if(c[x][y]=='R') y=e[3];
}
return ans;
}
void init1()
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
int t=i-1;
while(t>=1)
{
if(c[t][j]=='.') t--;
else
{
pi[i][j][0]=t;
break;
}
}
t=i+1;
while(t<=n)
{
if(c[t][j]=='.') t++;
else
{
pi[i][j][1]=t;
break;
}
}
t=j-1;
while(t>=1)
{
if(c[i][t]=='.') t--;
else
{
pi[i][j][2]=t;
break;
}
}
t=j+1;
while(t<=m)
{
if(c[i][t]=='.') t++;
else
{
pi[i][j][3]=t;
break;
}
}
}
}
}
void pp1()
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
for(int k=0;k<=3;k++)
{
qi[i][j][k]=pi[i][j][k];
}
}
}
}
int ff1(int x,int y)
{
int ans=0;
pp1();
while(1)
{
ans++;
int w;
if(c[x][y]=='U') w=qi[x][y][0];
if(c[x][y]=='D') w=qi[x][y][1];
if(c[x][y]=='L') w=qi[x][y][2];
if(c[x][y]=='R') w=qi[x][y][3];
if(w==0) break;
int e[4];
for(int i=0;i<=3;i++) e[i]=qi[x][y][i];
if(e[0]!=0)
{
qi[e[0]][y][1]=e[1];
}
if(e[1]!=0)
{
qi[e[1]][y][0]=e[0];
}
if(e[2]!=0)
{
qi[x][e[2]][3]=e[3];
}
if(e[3]!=0)
{
qi[x][e[3]][2]=e[2];
}
if(c[x][y]=='U') x=e[0];
else if(c[x][y]=='D') x=e[1];
else if(c[x][y]=='L') y=e[2];
else if(c[x][y]=='R') y=e[3];
}
return ans;
}
char cc;
int main()
{
scanf("%d%d",&n,&m);
cc=getchar();
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cc=getchar();
c[i][j]=cc;
}
cc=getchar();
}
int ansx=0;
int ansy=0;
if(n>=m)
{
init();
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(c[i][j]=='.') continue;
int tt=ff(i,j);
if(tt>ansx)
{
ansx=tt;
ansy=1;
}
else if(tt==ansx)
{
ansy++;
}
}
}
}
else
{
init1();
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(c[i][j]=='.') continue;
int tt=ff1(i,j);
if(tt>ansx)
{
ansx=tt;
ansy=1;
}
else if(tt==ansx)
{
ansy++;
}
}
}
}
printf("%d %d",ansx,ansy);
return 0;
}

http://codeforces.com/problemset/problem/277/C 还算挺有意思的一个博弈论。 本质上我们发现,每一条线就相当于nim游戏中的一堆石子。 然后当ans^a[i]<=a[i]时,我们可以在这堆石子上取,证明比较显然... 依然很难写...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
#include<bits/stdc++.h>
using namespace std;
#define PII pair<int,int>
#define pb push_back
#define mk make_pair
#define x first
#define y second
int n,m,k;
map<int,vector<PII > > lie;
map<int,vector<PII > > ha;
map<int,bool> vl;
map<int,bool> vh;
map<int,int> hl;
map<int,int> hh;
int xa,ya,xb,yb;
int hhh=0;
int ll=0;
int ans=0;
int main()
{
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=k;i++)
{
scanf("%d%d%d%d",&xa,&ya,&xb,&yb);
if(xa==xb)
{
if(vl.find(xa)==vl.end()) vl[xa]=1,ll++;
if(ya>yb) swap(ya,yb);
lie[xa].pb(mk(ya,yb));
}
else
{
if(vh.find(ya)==vh.end()) vh[ya]=1,hhh++;
if(xa>xb) swap(xa,xb);
ha[ya].pb(mk(xa,xb));
}
}
ll=n-1-ll;
hhh=m-1-hhh;
if(ll%2) ans^=m;
if(hhh%2) ans^=n;
for(int i=1;i<n;i++)
{
if(vl.find(i)==vl.end())
{
hl[i]=m;
break;
}
}
for(int i=1;i<m;i++)
{
if(vh.find(i)==vh.end())
{
hh[i]=n;
break;
}
}
for(auto &i: lie)
{
sort(i.y.begin(),i.y.end());
int pp=0;
pp=i.y[0].y-i.y[0].x;
int tt=i.y[0].y;
for(int k=1;k<i.y.size();k++)
{
if(i.y[k].x<=tt)
{
if(i.y[k].y>tt) pp+=i.y[k].y-tt,tt=i.y[k].y;
}
else
{
pp+=i.y[k].y-i.y[k].x;
tt=i.y[k].y;
}
}
hl[i.x]=m-pp;
ans^=(m-pp);
}
for(auto &i: ha)
{
sort(i.y.begin(),i.y.end());
int pp=0;
pp=i.y[0].y-i.y[0].x;
int tt=i.y[0].y;
for(int k=1;k<i.y.size();k++)
{
if(i.y[k].x<=tt)
{
if(i.y[k].y>tt) pp+=i.y[k].y-tt,tt=i.y[k].y;
}
else
{
pp+=i.y[k].y-i.y[k].x;
tt=i.y[k].y;
}
}
hh[i.x]=n-pp;
ans^=(n-pp);
}
if(ans)
{
cout<<"FIRST"<<endl;
for(auto &i: hh)
{
int pp=ans^i.second;
if(pp<=i.second)
{
pp=i.second-pp;
if(ha.find(i.x)==ha.end())
{
printf("%d %d %d %d\n",0,i.x,pp,i.x);
}
else
{
printf("%d %d ",0,i.x);
int yy=0;
if(ha[i.x][0].x>=pp)
{
printf("%d %d\n",pp,i.x);
return 0;
}
yy=ha[i.x][0].x;
pp-=yy;
yy=ha[i.x][0].y;
for(int k=1;k<ha[i.x].size();k++)
{
if(ha[i.x][k].x<=yy)
{
yy=max(yy,ha[i.x][k].y);
}
else
{
if(ha[i.x][k].x-yy>=pp)
{
yy+=pp;
printf("%d %d\n",yy,i.x);
return 0;
}
else
{
pp-=ha[i.x][k].x-yy;
yy=max(yy,ha[i.x][k].y);
}
}
}
yy+=pp;
printf("%d %d\n",yy,i.x);
}
return 0;
}
}
for(auto &i: hl)
{
int pp=ans^i.second;
if(pp<=i.second)
{
pp=i.second-pp;
if(lie.find(i.x)==lie.end())
{
printf("%d %d %d %d\n",i.x,0,i.x,pp);
}
else
{
printf("%d %d %d ",i.x,0,i.x);
int yy=0;
if(lie[i.x][0].x>=pp)
{
printf("%d\n",pp);
return 0;
}
yy=lie[i.x][0].x;
pp-=yy;
yy=lie[i.x][0].y;
for(int k=1;k<lie[i.x].size();k++)
{
//cout<<yy<<" ******"<<" "<<lie[i.x][k].x<<" "<<lie[i.x][k].y<<endl;
if(lie[i.x][k].x<=yy)
{
yy=max(yy,lie[i.x][k].y);
}
else
{
if(lie[i.x][k].x-yy>=pp)
{
yy+=pp;
printf("%d\n",yy);
return 0;
}
else
{
pp-=lie[i.x][k].x-yy;
yy=max(yy,lie[i.x][k].y);
}
}
}
yy+=pp;
printf("%d\n",yy);
}
return 0;
}
}
}
else cout<<"SECOND"<<endl;
return 0;
}

http://codeforces.com/problemset/problem/476/E 挺有趣的一个DP dp[i][j]代表走了前i个字符,删去了j个字符,最多匹配了多少个串。 对于每一个位置,我们可以知道删去多少个字符,可以出现一个最近的匹配串。 这样的话,暴力转移就好了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include<bits/stdc++.h>
using namespace std;
int dp[2010][2010]={};
char a[2010]={};
char p[2010]={};
int n,m;
int ff(int x)
{
if(x<m) return 2147483600;
int t=m;
int b=x;
int tp=0;
//cout<<x<<" ****"<<endl;
while(t&&b)
{
if(p[t]==a[b]) t--,b--;
else tp++,b--;
}
if(t==0)
{
return x-b-m;
}
else
{
return 2147483600;
}
}
int main()
{
scanf("%s",a+1);
scanf("%s",p+1);
n=strlen(a+1);
m=strlen(p+1);
for(int i=0;i<=n;i++)
{
for(int j=i+1;j<=n;j++) dp[i][j]=-2147483600;
}
for(int i=1;i<=n;i++)
{
int k=ff(i);
for(int j=0;j<=n;j++)
{
dp[i][j]=max(dp[i][j],dp[i-1][j]);
}
for(int j=0;j<=n;j++)
{
if(j>=k) dp[i][j]=max(dp[i][j],dp[i-k-m][j-k]+1);
}
}
for(int i=0;i<=n;i++)
{
printf("%d",dp[n][i]);
if(i!=n) printf(" ");
}
return 0;
}

http://codeforces.com/problemset/problem/190/E 补图上的bfs,是一个挺常见的套路... 但是时间复杂度还不是很懂...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#include<bits/stdc++.h>
using namespace std;
int n,m;
int a,b;
vector<int> ha[500010];
set<int> s;
int tt=0;
queue<int> q;
vector<int> e[500010];
queue<int> o;
int cmp(int x,int y)
{
return x<y;
}
void bfs(int x)
{
while(!q.empty()) q.pop();
while(!o.empty()) o.pop();
tt++;
q.push(x);
s.erase(x);
while(!q.empty())
{
x=q.front();
e[tt].push_back(x);
q.pop();
int w=0;
for(auto &i: s)
{
if(ha[x].size()!=0)
{
while(w+1!=ha[x].size())
{
if(i>ha[x][w]) w++;
else break;
}
if(i!=ha[x][w])
{
q.push(i);
o.push(i);
}
}
else
{
q.push(i);
o.push(i);
}
}
while(!o.empty()) s.erase(o.front()),o.pop();
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
scanf("%d%d",&a,&b);
ha[a].push_back(b);
ha[b].push_back(a);
}
for(int i=1;i<=n;i++)
{
if(ha[i].size()!=0) sort(ha[i].begin(),ha[i].end(),cmp);
}
for(int i=1;i<=n;i++) s.insert(i);
for(int i=1;i<=n;i++)
{
if(s.find(i)!=s.end()) bfs(i);
}
printf("%d\n",tt);
for(int i=1;i<=tt;i++)
{
printf("%d ",e[i].size());
for(int j=0;j<e[i].size();j++)
{
printf("%d ",e[i][j]);
}
printf("\n");
}
return 0;
}