辣鸡CF 毁我青春
ABC三题都很SB,但需要大讨论之术或者代码写起来容易出错
D题一个一眼题,但写起来神烦,最终还卡了我数组大小
E我没看
最后C题惨遭FST,D后来改了改数组大小就过了,E还是没看
总结:不会写代码了
说白了还是人弱……
跪膜没FST并且rank44并且rating涨了二百多的yzy
掉了六十多rating,竟然这么少 不科学
A
题意:给一个排列,要求必须交换一次使得1和n的位置离得最远。
SB题,要特判一下奇怪的东西……代码写的丑
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<stack>
using namespace std;
typedef long long LL;
const int SZ = 200010;
const int INF = 1000000010;
int read()
{
int n = 0;
char a = getchar();
bool flag = 0;
while(a > '9' || a < '0') { if(a == '-') flag = 1; a = getchar(); }
while(a >= '0' && a <= '9') { n = n * 10 + a - '0'; a = getchar(); }
if(flag) n = -n;
return n;
}
int num[SZ];
int main()
{
int n = read();
int pos1,pos2;
for(int i = 1;i <= n;i ++)
{
num[i] = read();
if(num[i] == 1) pos1 = i;
if(num[i] == n) pos2 = i;
}
if(n == 1)
{
printf("0"); return 0;
}
if(n == 2)
{
printf("1"); return 0;
}
if(((pos1 == 1 && pos2 == n) || (pos1 == n || pos2 == 1)))
{
printf("%d",n - 1);
return 0;
}
printf("%d\n",max(max(abs(n - pos1),abs(1 - pos1)),max(abs(n - pos2),abs(1 - pos2))));
return 0;
}
B
题意:给n行杯子,构成金字塔形,其中第i行i个杯子。每分钟往顶层的杯子灌一个杯子的量的水,问n排杯子在t时刻后有多少个杯子是满的。
n<=10,0<=t<=10000
我竟然画了半天杨辉三角,最后还是写的模拟……这告诉我们不需要去想一些高端的算法只要能过就行了……
还有t=0的情况……
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long LL;
const int SZ = 200010;
const int INF = 1000000010;
int read()
{
int n = 0;
char a = getchar();
bool flag = 0;
while(a > '9' || a < '0') { if(a == '-') flag = 1; a = getchar(); }
while(a >= '0' && a <= '9') { n = n * 10 + a - '0'; a = getchar(); }
if(flag) n = -n;
return n;
}
double bz[233][233],mi[233];
int n,t;
void dfs(int x,int y,double d)
{
if(x == n + 1) return ;
if(bz[x][y] == 1)
dfs(x + 1,y,d / 2),dfs(x + 1,y + 1,d / 2);
else
bz[x][y] += d;
return ;
}
int main()
{
n = read(),t = read();
double xxx = 1;
for(int i = 1;i <= n;i ++)
mi[i] = xxx,xxx /= 2.0;
while(t --)
dfs(1,1,1);
int ans = 0;
for(int i = 1;i <= n;i ++)
for(int j = 1;j <= i;j ++)
if(abs(bz[i][j] - 1.0) < 1e-8)
ans ++;
printf("%d",ans);
return 0;
}
C
题意:给一个只含有a和b的字符串,要求最多修改k个字符使得最长连续相同字符长度最长。输出最长长度。
n<=10w,0<=k<=n
把a和b的出现位置单独存起来,每次修改k个字符必定是连续的k个a或者k个b,答案可以由区间左右端点所在位置更新。注意要由n或1更新的情况。
若有少于k个a或者k个b,答案是n
还要判一下k=0的情况。
FST原因:k=0的时候,没有判由1或者n更新的情况。
浪费大量时间原因:vector的.size()是unsigned类型,当vector为空的时候,.size()-1会RE
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
typedef long long LL;
const int SZ = 200010;
const int INF = 1000000010;
int read()
{
int n = 0;
char a = getchar();
bool flag = 0;
while(a > '9' || a < '0') { if(a == '-') flag = 1; a = getchar(); }
while(a >= '0' && a <= '9') { n = n * 10 + a - '0'; a = getchar(); }
if(flag) n = -n;
return n;
}
vector<int> a,b;
char s[SZ];
int main()
{
int n = read(),k = read();
scanf("%s",s + 1);
for(int i = 1;i <= n;i ++)
if(s[i] == 'a') a.push_back(i);
else b.push_back(i);
if(k == 0)
{
int ans = 0;
for(int i = 0;i < (int)a.size() - 1;i ++)
ans = max(ans,a[i + 1] - 1 - (a[i] + 1) + 1);
if(a.size() == 1)
ans = max(ans,max(a[0] - 1,n - a[0]));
for(int i = 0;i < (int)b.size() - 1;i ++)
ans = max(ans,b[i + 1] - 1 - (b[i] + 1) + 1);
if(b.size() == 1)
ans = max(ans,max(b[0] - 1,n - b[0]));
if(a.size() <= k || b.size() <= k)
ans = n;
printf("%d\n",ans);
return 0;
}
int ans = 0;
for(int i = 0;i < (int)a.size();i ++)
{
int r = i + k - 1;
if(r >= a.size()) break;
if(i == 0)
{
if(r + 1 >= 0 && r + 1 < a.size())
ans = max(ans,a[r + 1] - 1);
}
else if(r == (int)a.size() - 1)
{
if(i - 1 >= 0)
ans = max(ans,n - (a[i - 1] + 1) + 1);
}
else
{
if(r + 1 >= 0 && r + 1 < a.size() && i - 1 >= 0)
ans = max(ans,(a[r + 1] - 1) - (a[i - 1] + 1) + 1);
}
}
for(int i = 0;i < (int)b.size();i ++)
{
int r = i + k - 1;
if(r >= b.size()) break;
if(i == 0)
{
if(r + 1 >= 0 && r + 1 < b.size())
ans = max(ans,b[r + 1] - 1);
}
else if(r == (int)b.size() - 1)
{
if(i - 1 >= 0)
ans = max(ans,n - (b[i - 1] + 1) + 1);
}
else
{
if(r + 1 >= 0 && r + 1 < b.size() && i - 1 >= 0)
ans = max(ans,(b[r + 1] - 1) - (b[i - 1] + 1) + 1);
}
}
if(a.size() <= k || b.size() <= k)
ans = n;
printf("%d",ans);
return 0;
}
D
题意:n*m的迷宫,每个格子有四面,每一面都有可能有门,这样一共是16种格子。每分钟你可以从一个格子透过门走到另一个相邻的格子,要求两个格子都有相应的门;或者人原地不动,所有的格子原地瞬时针旋转90度。问给定起点到给定终点的最短路。
n<=m<=1000
SB分层图BFS,代码神烦
边数在全都是四连通的时候达到最大,大概边要达到一千多万,数组开2000w比较保险
数组开小他说我TLE,我以为On算法被卡常,调了半天……
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>
#include<queue>
using namespace std;
typedef long long LL;
const int SZ = 4000010;
const int INF = 1000000010;
int read()
{
int n = 0;
char a = getchar();
bool flag = 0;
while(a > '9' || a < '0') { if(a == '-') flag = 1; a = getchar(); }
while(a >= '0' && a <= '9') { n = n * 10 + a - '0'; a = getchar(); }
if(flag) n = -n;
return n;
}
string mp[200];
const int dx[] = {0,1,0,-1};
const int dy[] = {1,0,-1,0};//右 下 左 上
char maps[1010][1010];
int n,m;
bool iscan(int x,int y)
{
return x >= 1 && x <= n && y >= 1 && y <= m;
}
int getnode(int x,int y,int d)
{
return (x - 1) * m + y + (d - 1) * n * m;
}
int head[SZ],nxt[20000000],tot = 1;
struct edge{
int t;
bool d;
}l[20000000];
void build(int f,int t,int d)
{
l[++ tot] = (edge){t,d};
nxt[tot] = head[f]; head[f] = tot;
}
bool vis[SZ];
struct haha{
int u,d;
};
queue<haha> q;
int bfs(int s,int e)
{
q.push((haha){s,0});
vis[s] = 1;
while(q.size())
{
haha f = q.front(); q.pop();
for(int i = head[f.u];i;i = nxt[i])
{
int v = l[i].t;
if(!vis[v])
{
vis[v] = 1;
if(v == e) return f.d + l[i].d;
q.push((haha){v,f.d + l[i].d});
}
}
}
return -1;
}
int main()
{
mp['+'] = "1111";
mp['-'] = "1010";
mp['|'] = "0101";
mp['^'] = "0001";
mp['>'] = "1000";
mp['<'] = "0010";
mp['v'] = "0100";
mp['L'] = "1101";
mp['R'] = "0111";
mp['U'] = "1110";
mp['D'] = "1011";
mp['*'] = "0000";
n = read(),m = read();
for(int i = 1;i <= n;i ++)
gets(maps[i] + 1);
int sx = read(),sy = read(),ex = read(),ey = read();
for(int p = 1;p <= 4;p ++)
{
for(int i = 1;i <= n;i ++)
{
for(int j = 1;j <= m;j ++)
{
for(int k = 0;k < 4;k ++)
{
int p1 = (k - (p - 1) + 4) % 4;
int p2 = (p1 + 2) % 4;
int x = i + dx[k],y = j + dy[k];
if(iscan(x,y))
{
if(mp[maps[i][j]][p1] == '1' && mp[maps[x][y]][p2] == '1')
build(getnode(i,j,p),getnode(x,y,p),1);//printf("%d %d %d %d %d %d %d %d\n",i,j,x,y,p1,p2,p,k);
}
}
}
}
}
for(int i = 1;i <= n;i ++)
{
for(int j = 1;j <= m;j ++)
{
build(getnode(i,j,1),getnode(i,j,2),1);
build(getnode(i,j,2),getnode(i,j,3),1);
build(getnode(i,j,3),getnode(i,j,4),1);
build(getnode(i,j,4),getnode(i,j,1),1);
}
}
int e = n * m * 4 + 1;
build(getnode(ex,ey,1),e,0);
build(getnode(ex,ey,2),e,0);
build(getnode(ex,ey,3),e,0);
build(getnode(ex,ey,4),e,0);
printf("%d",bfs(getnode(sx,sy,1),e));
return 0;
}
/*
2 3
<><
><>
1 1
1 1
*/