ZROI 8.8 交互、通信、提答题
ZROI 8.8 交互、通信、提答题

知识点总结(其实没什么知识点,就是一些要注意的地方)

1.交互题

  • 每次输出后记得使用<<endl或者fflush(stdout)刷新缓冲区
  • 注意题目类型是IO交互题还是函数交互题,若为函数交互题则需注意是否要引用头文件
  • 注意利用好下发文件

2.通信题

  • 可以理解为实现两个互相调用的交互库
  • 注意传递信息的限制
  • 注意是否有Alice和Bob

3.提交答案题

  • 注意细心观察即可

今日题目总结

A – Guess the Array

注意到 n3n≥3 ,首先进行三次询问,分别为:

  • ? 1 2
  • ? 2 3
  • ? 1 3

我们就可以得到询问出来的两数之和以及相加后可以得到前三个数的和的两倍,那么除以二就是这三个数的和

于是就可以求出这三个数。最后用这三个数中的任意一个与其他的数求和即可,询问次数为 nn

#include <bits/stdc++.h>
using namespace std;
#define int long long
int ans[5005];
signed main(){
    int n,sum,tmp1,tmp2,tmp3;
    cin>>n;
    cout<<"? 1 2"<<endl;
    cin>>tmp1;
    sum+=tmp1;
    cout<<"? 2 3"<<endl;
    cin>>tmp2;
    sum+=tmp2;
    cout<<"? 1 3"<<endl;
    cin>>tmp3;
    sum+=tmp3;
    sum/=2;
    ans[1]=sum-tmp2;
    ans[2]=sum-tmp3;
    ans[3]=sum-tmp1;
    for(int i=4;i<=n;++i)
    {
        cout<<"? 1 "<<i<<endl;
        cin>>tmp1;
        ans[i]=tmp1-ans[1];
    }
    cout<<"! ";
    for(int i=1;i<=n;++i)
    {
        cout<<ans[i]<<" ";
    }
    return 0;
}

B – 元旦激光炮

直接排除法(只是感觉比二分好写一点)

在三个有序数组中,每次比较各数组第 k÷3k÷3 个位置的元素,最小值所在数组的前 k÷3k÷3 个元素一定可以被安全排除

通过不断将被排除的元素数量从 kk 中减去,循环直至 kk 变为 00,最终记录的 ansans 即为第 kk 小的值。

#include <bits/stdc++.h>
#include "kth.h"
using namespace std;
int query_kth(int n_a,int n_b,int n_c,int k)
{
    int ans=0,ca=-1,cb=-1,cc=-1;
    while(k)
    {
        int l=(k+2)/3;
        int va=get_a(ca+l),vb=get_b(cb+l),vc=get_c(cc+l);
        if(va<=vb&&va<=vc)
        {
            ans=max(ans,va);
            ca+=l;
            k-=l;
        }
        else if(vb<=vc)
        {
            ans=max(ans,vb);
            cb+=l;
            k-=l;
        }
        else
        {
            ans=max(ans,vc);
            cc+=l;
            k-=l;
        }
    }
    return ans;
}

C – ace5 and Task Order

和快排差不多的思路

随机选择一个数组元素作为基准,通过交互查询将其余元素与基准比较,递归地划分出小于和大于基准的两部分,最终确定每个元素的排名

利用随机化来避免被单调数据卡住,期望时间复杂度为 O(nlogn)O(n \log n)

#include <bits/stdc++.h>
using namespace std;
#define int long long
int ans[2005];
char ch;
vector<int> p;
void quick_sort(int l,vector<int> a)
{
    int x=rand()%a.size();
    cout<<"? "<<a[x]<<endl;
    cin>>ch;
    while(ch!='=')
    {
        cout<<"? "<<a[x]<<endl;
        cin>>ch;
    }
    vector<int> b,c;
    for(int i=0;i<a.size();++i)
    {
        if(i==x)
        {
            continue;
        }
        cout<<"? "<<a[i]<<endl;
        cin>>ch;
        if(ch=='<')
        {
            b.push_back(a[i]);
        }
        else
        {
            c.push_back(a[i]);
        }
        cout<<"? "<<a[x]<<endl;
        cin>>ch;
    }
    ans[a[x]]=l+b.size();
    if(b.size())
    {
        quick_sort(l,b);
    }
    if(c.size())
    {
        quick_sort(l+b.size()+1,c);
    }
}
signed main(){
    srand(chrono::steady_clock::now().time_since_epoch().count());
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
        p.clear();
        for(int i=1;i<=n;++i)
        {
            p.push_back(i);
        }
        quick_sort(1,p);
        cout<<"! ";
        for(int i=1;i<=n;++i)
        {
            cout<<ans[i]<<" ";
        }
        cout<<endl;
    }
    return 0;
}

D – GCD Queries

注意到题目定义 gcd(0,x)=xgcd(0,x)=x,容易发现以下性质:

  • 如果gcd(a,b)=gcd(a,c)gcd(a,b)=gcd(a,c),则a0a≠0
  • 如果gcd(a,b)<gcd(a,c)gcd(a,b)<gcd(a,c),则b0b≠0
  • 如果gcd(a,b)>gcd(a,c)gcd(a,b)>gcd(a,c),则c0c≠0

将所有编号加入集合中,每次选集合中的三个数进行上面的判断,发现哪个数不为 $0$ 则将其从集合中删去,直到剩下最后两个数

#include <bits/stdc++.h>
using namespace std;
#define int long long
signed main(){
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
        set<int> s;
        for(int i=1;i<=n;++i)
        {
            s.insert(i);
        }
        while(s.size()>2)
        {
            int cnt=0;
            int a1=-1,a2=-1,a3=-1;
            for(auto it=s.begin();it!=s.end();++it)
            {
                ++cnt;
                if(a1==-1)
                {
                    a1=*it;
                }
                else if(a2==-1)
                {
                    a2=*it;
                }
                else
                {
                    a3=*it;
                }
                if(cnt==3)
                {
                    break;
                }
            }
            cout<<"? "<<a1<<" "<<a2<<endl;
            int gcd1;
            cin>>gcd1;
            cout<<"? "<<a1<<" "<<a3<<endl;
            int gcd2;
            cin>>gcd2;
            if(gcd1==gcd2)
            {
                s.erase(a1);
            }
            else if(gcd1<gcd2)
            {
                s.erase(a2);
            }
            else
            {
                s.erase(a3);
            }
        }
        cout<<"! ";
        for(auto it=s.begin();it!=s.end();++it)
        {
            cout<<*it<<" ";
        }
        cout<<endl;
        int res;
        cin>>res;
        if(res==-1)
        {
            exit(0);
        }
    }
    return 0;
}

E – Deleting Numbers

先用线性筛找出所有不超过 nn 的质数

将质数分块,对每个质数执行 B 操作删除其倍数并记录删除数量,若返回值与预期不符,则说明 xx 含有该质因子,进而通过 A 操作查询其幂次来确定具体指数

每处理完一个质数块后执行 A 1 查询。若集合剩余数量与预期不符,说明 xx 的最小质因子就在刚处理的这个块中,随后在该块内逐个质数排查以精确定位

对于超过 n\sqrt n 的大质数,因其指数最多为 11,只需在分块过程中确认其是否存在即可

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=100005;
bool vis[N],iscomp[N];
int prime[N],tot;
int n,x,sum,ans;
bool found;
inline void read(int &n)
{
    int x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-')
        {
            f=-1;
        }
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        x=x*10+ch-'0';
        ch=getchar();
    }
    n=x*f;
}
inline void write(int x)
{
    if(x<0)
    {
        putchar('-');
        x=-x;
    }
    if(x>9)
    {
        write(x/10);
    }
    putchar(x%10+'0');
    return;
}
signed main(){
    read(n);
    if(n==1)
    {
        printf("C 1\n");
        fflush(stdout);
        return 0;
    }
    for(int i=2;i<=n;++i)
    {
        if(!iscomp[i])
        {
            prime[++tot]=i;
        }
        for(int j=1;j<=tot&&i*prime[j]<=n;++j)
        {
            iscomp[i*prime[j]]=true;
            if(i%prime[j]==0)
            {
                break;
            }
        }
    }
    memset(vis,0,sizeof(vis));
    sum=n;
    ans=1;
    found=false;
    int k=(int)sqrt(tot)+1;
    for(int i=1;i<=tot;++i)
    {
        if(i>=k&&ans*prime[i-k+1]>n)
        {
            break;
        }
        printf("B %lld\n",prime[i]);
        fflush(stdout);
        int cnt=0;
        for(int j=prime[i];j<=n;j+=prime[i])
        {
            if(!vis[j])
            {
                ++cnt;
                --sum;
                vis[j]=true;
            }
        }
        read(x);
        if(x!=cnt)
        {
            for(int pwr=prime[i];pwr<=n;pwr*=prime[i])
            {
                printf("A %lld\n",pwr);
                fflush(stdout);
                read(x);
                if(x)
                {
                    ans*=prime[i];
                }
                else
                {
                    break;
                }
            }
        }
        if((i==tot||i%k==0)&&!found)
        {
            printf("A 1\n");
            fflush(stdout);
            read(x);
            if(x!=sum)
            {
                int start=i-k+1;
                if(start<1)
                {
                    start=1;
                }
                for(int j=start;j<=i;++j)
                {
                    for(int pwr=prime[j];pwr<=n;pwr*=prime[j])
                    {
                        printf("A %lld\n",pwr);
                        fflush(stdout);
                        read(x);
                        if(x)
                        {
                            ans*=prime[j];
                            found=true;
                        }
                        else
                        {
                            break;
                        }
                    }
                    if(found)
                    {
                        break;
                    }
                }
            }
        }
    }
    printf("C %lld\n",ans);
    fflush(stdout);
    return 0;
}

F – Rin and The Unknown Flower

其实我调了一中午提交十多遍都是错的我也很sad

分类讨论一下

对于 n>4n>4 的情况,询问CC、CH、CO得到除最后一个位置的C;询问HH、OH得到除第一个位置的H。则除第一个位置和最后一个位置外还没确定的全为O,最后枚举剩下至多四种情况

对于 n=4n=4 的情况,依次查 CC, CH, CO;若有出现则枚举所有候选,必要时用候选串查询区分;若无则查 HO;若无则查 OO;若无则查 HHH,每次筛选候选(最后一步唯一),输出最终字符串

然后是蒟蒻因为不想写函数搞出来的整整540行代码

#include <bits/stdc++.h>
using namespace std;
#define int long long
char p[55];
signed main(){
    int t;
    cin>>t;
    while(t--)
    {
        int n;
        cin>>n;
        for(int i=1;i<=n;++i)
        {
            p[i]=0;
        }
        if(n>4)
        {
            cout<<"? CH"<<endl;
            int k;
            cin>>k;
            if(k==-1)
            {
                exit(0);
            }
            for(int i=1;i<=k;++i)
            {
                int a;
                cin>>a;
                p[a]='C';
                p[a+1]='H';
            }
            cout<<"? CO"<<endl;
            cin>>k;
            if(k==-1)
            {
                exit(0);
            }
            for(int i=1;i<=k;++i)
            {
                int a;
                cin>>a;
                p[a]='C';
                p[a+1]='O';
            }
            cout<<"? CC"<<endl;
            cin>>k;
            if(k==-1)
            {
                exit(0);
            }
            for(int i=1;i<=k;++i)
            {
                int a;
                cin>>a;
                p[a]=p[a+1]='C';
            }
            cout<<"? OH"<<endl;
            cin>>k;
            if(k==-1)
            {
                exit(0);
            }
            for(int i=1;i<=k;++i)
            {
                int a;
                cin>>a;
                p[a]='O';
                p[a+1]='H';
            }
            cout<<"? HH"<<endl;
            cin>>k;
            if(k==-1)
            {
                exit(0);
            }
            for(int i=1;i<=k;++i)
            {
                int a;
                cin>>a;
                p[a]=p[a+1]='H';
            }
            for(int i=2;i<n;++i)
            {
                if(!p[i])
                {
                    p[i]='O';
                }
            }
            int cnt1=2,cnt2=2;
            char mj1[2]={'H','O'};
            char mj2[2]={'C','O'};
            if(p[1]!=0)
            {
                mj1[0]=p[1];
                cnt1=1;
            }
            if(p[n]!=0)
            {
                mj2[0]=p[n];
                cnt2=1;
            }
            int is_completed=0;
            for(int i=0;i<cnt1;++i)
            {
                if(is_completed)
                {
                    break;
                }
                for(int j=0;j<cnt2;++j)
                {
                    if(is_completed)
                    {
                        break;
                    }
                    p[1]=mj1[i];
                    p[n]=mj2[j];
                    if(i==cnt1-1&&j==cnt2-1)
                    {
                        is_completed=1;
                        int tmp;
                        cout<<"! ";
                        for(int l=1;l<=n;++l)
                        {
                            cout<<p[l];
                        }
                        cout<<endl;
                        cin>>tmp;
                        if(!tmp)
                        {
                            exit(0);
                        }
                        break;
                    }
                    cout<<"? ";
                    for(int l=1;l<=n;++l)
                    {
                        cout<<p[l];
                    }
                    cout<<endl;
                    cin>>k;
                    if(k==1)
                    {
                        is_completed=1;
                        int tmp;
                        cin>>tmp;
                        cout<<"! ";
                        for(int l=1;l<=n;++l)
                        {
                            cout<<p[l];
                        }
                        cout<<endl;
                        cin>>tmp;
                        if(!tmp)
                        {
                            exit(0);
                        }
                    }
                    if(is_completed)
                    {
                        break;
                    }
                }
            }
        }
        else
        {
            string q2[3]={"CC","CH","CO"};
            vector<int> r2[3];
            bool any=false;
            for(int i=0;i<3;++i)
            {
                cout<<"? "<<q2[i]<<endl;
                int k;
                cin>>k;
                if(k==-1)
                {
                    exit(0);
                }
                for(int j=0;j<k;++j)
                {
                    int pos;
                    cin>>pos;
                    r2[i].push_back(pos);
                }
                if(k>0)
                {
                    any=true;
                }
            }
            if(any)
            {
                vector<pair<string,vector<int>>> qs;
                for(int i=0;i<3;++i)
                {
                    qs.push_back({q2[i],r2[i]});
                }
                vector<string> cands;
                string chars="CHO";
                for(int mask=0;mask<81;++mask)
                {
                    string cand;
                    int tmp=mask;
                    for(int i=0;i<4;++i)
                    {
                        cand+=chars[tmp%3];
                        tmp/=3;
                    }
                    bool ok=true;
                    for(auto &q:qs)
                    {
                        string s=q.first;
                        vector<int> exp=q.second;
                        vector<int> got;
                        int len=s.size();
                        for(int st=0;st+len<=4;++st)
                        {
                            if(cand.substr(st,len)==s)
                            {
                                got.push_back(st+1);
                            }
                        }
                        if(got!=exp)
                        {
                            ok=false;
                            break;
                        }
                    }
                    if(ok)
                    {
                        cands.push_back(cand);
                    }
                }
                string ans;
                if(cands.size()==1)
                {
                    ans=cands[0];
                }
                else
                {
                    for(int idx=0;idx<(int)cands.size()-1;++idx)
                    {
                        cout<<"? "<<cands[idx]<<endl;
                        int k;
                        cin>>k;
                        if(k==-1)
                        {
                            exit(0);
                        }
                        if(k==1)
                        {
                            int pos;
                            cin>>pos;
                            if(pos==1)
                            {
                                ans=cands[idx];
                                break;
                            }
                        }
                    }
                    if(ans.empty())
                    {
                        ans=cands.back();
                    }
                }
                cout<<"! "<<ans<<endl;
                int tmp;
                cin>>tmp;
                if(tmp==0)
                {
                    exit(0);
                }
                continue;
            }
            cout<<"? HO"<<endl;
            int k;
            cin>>k;
            if(k==-1)
            {
                exit(0);
            }
            vector<int> rHO;
            for(int i=0;i<k;++i)
            {
                int pos;
                cin>>pos;
                rHO.push_back(pos);
            }
            if(k>0)
            {
                vector<pair<string,vector<int>>> qs;
                for(int i=0;i<3;++i)
                {
                    qs.push_back({q2[i],r2[i]});
                }
                qs.push_back({"HO",rHO});
                vector<string> cands;
                string chars="CHO";
                for(int mask=0;mask<81;++mask)
                {
                    string cand;
                    int tmp=mask;
                    for(int i=0;i<4;++i)
                    {
                        cand+=chars[tmp%3];
                        tmp/=3;
                    }
                    bool ok=true;
                    for(auto &q:qs)
                    {
                        string s=q.first;
                        vector<int> exp=q.second;
                        vector<int> got;
                        int len=s.size();
                        for(int st=0;st+len<=4;++st)
                        {
                            if(cand.substr(st,len)==s)
                            {
                                got.push_back(st+1);
                            }
                        }
                        if(got!=exp)
                        {
                            ok=false;
                            break;
                        }
                    }
                    if(ok)
                    {
                        cands.push_back(cand);
                    }
                }
                string ans;
                if(cands.size()==1)
                {
                    ans=cands[0];
                }
                else
                {
                    for(int idx=0;idx<(int)cands.size()-1;++idx)
                    {
                        cout<<"? "<<cands[idx]<<endl;
                        int k2;
                        cin>>k2;
                        if(k2==-1)
                        {
                            exit(0);
                        }
                        if(k2==1)
                        {
                            int pos;
                            cin>>pos;
                            if(pos==1)
                            {
                                ans=cands[idx];
                                break;
                            }
                        }
                    }
                    if(ans.empty())
                    {
                        ans=cands.back();
                    }
                }
                cout<<"! "<<ans<<endl;
                int tmp;
                cin>>tmp;
                if(tmp==0)
                {
                    exit(0);
                }
                continue;
            }
            cout<<"? OO"<<endl;
            cin>>k;
            if(k==-1)
            {
                exit(0);
            }
            vector<int> rOO;
            for(int i=0;i<k;++i)
            {
                int pos;
                cin>>pos;
                rOO.push_back(pos);
            }
            if(k>0)
            {
                vector<pair<string,vector<int>>> qs;
                for(int i=0;i<3;++i)
                {
                    qs.push_back({q2[i],r2[i]});
                }
                qs.push_back({"HO",rHO});
                qs.push_back({"OO",rOO});
                vector<string> cands;
                string chars="CHO";
                for(int mask=0;mask<81;++mask)
                {
                    string cand;
                    int tmp=mask;
                    for(int i=0;i<4;++i)
                    {
                        cand+=chars[tmp%3];
                        tmp/=3;
                    }
                    bool ok=true;
                    for(auto &q:qs)
                    {
                        string s=q.first;
                        vector<int> exp=q.second;
                        vector<int> got;
                        int len=s.size();
                        for(int st=0;st+len<=4;++st)
                        {
                            if(cand.substr(st,len)==s)
                            {
                                got.push_back(st+1);
                            }
                        }
                        if(got!=exp)
                        {
                            ok=false;
                            break;
                        }
                    }
                    if(ok)
                    {
                        cands.push_back(cand);
                    }
                }
                string ans;
                if(cands.size()==1)
                {
                    ans=cands[0];
                }
                else
                {
                    cout<<"? "<<cands[0]<<endl;
                    int k2;
                    cin>>k2;
                    if(k2==-1)
                    {
                        exit(0);
                    }
                    if(k2==1)
                    {
                        int pos;
                        cin>>pos;
                        if(pos==1)
                        {
                            ans=cands[0];
                        }
                        else
                        {
                            ans=cands[1];
                        }
                    }
                    else
                    {
                        ans=cands[1];
                    }
                }
                cout<<"! "<<ans<<endl;
                int tmp;
                cin>>tmp;
                if(tmp==0)
                {
                    exit(0);
                }
                continue;
            }
            cout<<"? HHH"<<endl;
            cin>>k;
            if(k==-1)
            {
                exit(0);
            }
            vector<int> rHHH;
            for(int i=0;i<k;++i)
            {
                int pos;
                cin>>pos;
                rHHH.push_back(pos);
            }
            vector<pair<string,vector<int>>> qs;
            for(int i=0;i<3;++i)
            {
                qs.push_back({q2[i],r2[i]});
            }
            qs.push_back({"HO",rHO});
            qs.push_back({"OO",rOO});
            qs.push_back({"HHH",rHHH});
            vector<string> cands;
            string chars="CHO";
            for(int mask=0;mask<81;++mask)
            {
                string cand;
                int tmp=mask;
                for(int i=0;i<4;++i)
                {
                    cand+=chars[tmp%3];
                    tmp/=3;
                }
                bool ok=true;
                for(auto &q:qs)
                {
                    string s=q.first;
                    vector<int> exp=q.second;
                    vector<int> got;
                    int len=s.size();
                    for(int st=0;st+len<=4;++st)
                    {
                        if(cand.substr(st,len)==s)
                        {
                            got.push_back(st+1);
                        }
                    }
                    if(got!=exp)
                    {
                        ok=false;
                        break;
                    }
                }
                if(ok)
                {
                    cands.push_back(cand);
                }
            }
            string ans=cands[0];
            cout<<"! "<<ans<<endl;
            int tmp;
            cin>>tmp;
            if(tmp==0)
            {
                exit(0);
            }
        }
    }
    return 0;
}

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇
Cover
加载中...
准备就绪