日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

Codeforces 1286C/1287E Madhouse (交互题)

發(fā)布時(shí)間:2025/3/15 编程问答 15 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Codeforces 1286C/1287E Madhouse (交互题) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

題目鏈接

C1: http://codeforces.com/contest/1286/problem/C1
C2: http://codeforces.com/contest/1286/problem/C2

題解

首先考慮C1怎么做: 先詢(xún)問(wèn)整個(gè)串,再詢(xún)問(wèn)前\((n-1)\)個(gè)字符。二者相比對(duì),對(duì)于每一個(gè)\(l=1..n\), 前者都比后者多一個(gè)長(zhǎng)度為\(l\)的字符串,也就是長(zhǎng)度為\(l\)的后綴。求出這些后綴是什么,然后后綴之間互相比對(duì),就可以知道每個(gè)位置的字符了。
考慮問(wèn)一遍整個(gè)串。位置\(i\)上的字符在整個(gè)串的長(zhǎng)度為\(l\)的子串(\(l\gt \frac{n}{2}\))共出現(xiàn)了\(\min(i,n-i+1,n-l+1)\)次。將\(l\)\((l+1)\)作差,那么剩下的就是\([n-l+1,l]\)這段區(qū)間內(nèi)的字符各出現(xiàn)了一次。再將作差后的\(l\)\((l-1)\)作差,剩下的是\(l\)\((n-l+1)\)這兩個(gè)字符。
但是剩下兩個(gè)字符非常難以判斷。考慮用剛才的方法求出前一半,去掉前一半的影響,就可以通過(guò)差出來(lái)的字符確定答案了。
總詢(xún)問(wèn)次數(shù)約\(0.75n^2\).
注意特判\(n=1\).

代碼

#include<bits/stdc++.h> #define llong long long using namespace std;inline int read() {int x = 0,f = 1; char ch = getchar();for(;!isdigit(ch);ch=getchar()) {if(ch=='-') f = -1;}for(; isdigit(ch);ch=getchar()) {x = x*10+ch-48;}return x*f; }const int N = 101; const int S = 26;char str[N+3];namespace Subtask {int a[N+3][N+3][S+3],cnta[N+3],b[N+3][N+3][S+3],cntb[N+3];bool fa[N+3][N+3],fb[N+3][N+3];int cur[S+3];char ans[N+3];void solve(int n,char ans[]){cout<<'?'<<' '<<1<<' '<<n-1<<' '<<endl; cout.flush();for(int i=1; i<=(n-1)*n/2; i++){cin>>str+1; int len = strlen(str+1);cnta[len]++; for(int j=1; j<=len; j++) a[len][cnta[len]][str[j]-96]++;}cout<<'?'<<' '<<1<<' '<<n<<' '<<endl; cout.flush();for(int i=1; i<=n*(n+1)/2; i++){cin>>str+1; int len = strlen(str+1);cntb[len]++; for(int j=1; j<=len; j++) b[len][cntb[len]][str[j]-96]++;}for(int i=1; i<=n; i++){int id = 0;for(int k=1; k<=cntb[i]; k++){bool found = false;for(int j=1; j<=cnta[i]; j++){if(fa[i][j]) continue;bool same = true;for(int s=1; s<=S; s++) {if(a[i][j][s]!=b[i][k][s]) {same = false; break;}}if(same) {found = true; fa[i][j] = true; break;}}if(!found) {id = k; break;}}for(int s=1; s<=S; s++){if(b[i][id][s]!=cur[s]) {cur[s]++; ans[n-i+1] = s+96; break;}}}} }int a[N+3][N+3][S+3],cnta[N+3]; int tot[N+3][S+3]; int dif[N+3][S+3]; char ans[N+3]; int n;int main() {cin>>n;if(n==1){cout<<'?'<<' '<<1<<' '<<1<<endl; cout.flush();cin>>ans;cout<<'!'<<' '<<ans<<endl; cout.flush();return 0;}else if(n==2){Subtask::solve(2,ans);cout<<'!'<<' '<<ans+1<<endl; cout.flush();return 0;}int nn = (n+1)>>1;Subtask::solve(nn,ans);cout<<'?'<<' '<<1<<' '<<n<<endl; cout.flush();for(int i=1; i<=n*(n+1)/2; i++){cin>>str+1; int len = strlen(str+1);cnta[len]++; for(int j=1; j<=len; j++) a[len][cnta[len]][j] = str[j]-96,tot[len][str[j]-96]++;}for(int l=nn+1; l<=n; l++){for(int i=1; i<=nn; i++){tot[l][ans[i]-96] -= min(i,n-l+1);} // printf("tot[%d]: ",l); for(int j=1; j<=S; j++) printf("%d ",tot[l][j]); puts("");}for(int l=nn+1; l<=n; l++){for(int i=1; i<=S; i++){dif[l][i] = tot[l][i]-tot[l+1][i];if(dif[l][i]!=dif[l-1][i]) {ans[l] = i+96;}}}cout<<'!'<<' '<<ans+1<<endl; cout.flush();return 0; }

總結(jié)

以上是生活随笔為你收集整理的Codeforces 1286C/1287E Madhouse (交互题)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。