标签:string == pop http queue ati can for 连通
题目链接:https://codeforces.com/contest/598
挺有意思的一条送分题。
题意:给一个长<=10000的字符串,然后<=300次询问,每次询问要求把[l,r]子串循环右移k<=1000000次。求最终的结果。
题解:感觉这题有个FHQTreap的解法。不过仔细想想看长度这么短,询问也这么少,直接把k模子串长度然后暴力就可以了。
char s[10005];
char tmp1[10005];
char tmp2[10005];
void test_case() {
scanf("%s", s + 1);
int n = strlen(s + 1), m;
scanf("%d", &m);
while(m--) {
int l, r, k;
scanf("%d%d%d", &l, &r, &k);
k %= (r - l + 1);
int t1top = 0, t2top = 0;
for(int i = l; i <= r - k; ++i)
tmp1[++t1top] = s[i];
for(int i = r - k + 1; i <= r; ++i)
tmp2[++t2top] = s[i];
tmp1[t1top + 1] = '\0';
tmp2[t2top + 1] = '\0';
for(int i = l, k = 1; k <= t2top; ++i, ++k)
s[i] = tmp2[k];
for(int i = l + t2top, k = 1; k <= t1top; ++i, ++k)
s[i] = tmp1[k];
}
puts(s + 1);
}
一个挺明显的挖油井问题,要数某个白格连通块中与白格接壤的黑格的不同面的数量。假如去掉同一个黑格的不同面,只需要在cntwall前判断一下有没有被当前白色连通块vis过,然后涂上这个连通块特有的颜色。
int di[4] = {0, 0, -1, 1};
int dj[4] = {-1, 1, 0, 0};
char g[1005][1005];
int vis[1005][1005];
int cnt[1005][1005];
queue<pii> Q1, Q2;
void bfs(int si, int sj, int color) {
vis[si][sj] = color;
Q1.push({si, sj});
Q2.push({si, sj});
int cntwall = 0;
while(!Q1.empty()) {
int ui = Q1.front().first, uj = Q1.front().second;
Q1.pop();
for(int k = 0; k < 4; ++k) {
int vi = ui + di[k];
int vj = uj + dj[k];
if(g[vi][vj] == '*')
++cntwall;
if(g[vi][vj] == '.' && vis[vi][vj] == 0) {
vis[vi][vj] = color;
Q1.push({vi, vj});
Q2.push({vi, vj});
}
}
}
while(!Q2.empty()) {
int ui = Q2.front().first, uj = Q2.front().second;
Q2.pop();
cnt[ui][uj] = cntwall;
}
}
void test_case() {
int n, m, q;
scanf("%d%d%d", &n, &m, &q);
for(int i = 1; i <= n; ++i)
scanf("%s", g[i] + 1);
int cntcolor = 0;
for(int i = 1; i <= n; ++i) {
for(int j = 1; j <= m; ++j) {
if(g[i][j] == '.' && vis[i][j] == 0)
bfs(i, j, ++cntcolor);
}
}
while(q--) {
int qi, qj;
scanf("%d%d", &qi, &qj);
printf("%d\n", cnt[qi][qj]);
}
}
Educational Codeforces Round 1
标签:string == pop http queue ati can for 连通
原文地址:https://www.cnblogs.com/KisekiPurin2019/p/12459840.html