• CF1292E. Rin and The Unknown Flower


    题目描述

    交互题

    有一个长度为n的由C,H,O组成的字符串S,每次可以询问一个串T,返回询问串在S中的位置,一次询问的代价是1/(|T|^2),在总代价<=7/5的代价下找出串S

    4<=n<=50

    题解

    非常有趣的题目,虽然没什么人切+及其难调+题解辣鸡

    不是题解做法因为根本没看,以下把CHO对应ABC

    n>=5

    首先这个代价就很神必,显然不可能询问所有的排列,也不可能询问单个字符

    仔细想一下,串太长没有卵用,太短代价太大,所以应该是在2和3最好

    一开始想的是询问AA,BB,CC以及ABC的排列,发现代价超了并且好像找不出来

    xjb思考后考虑询问AA,AB,AC,BC,CB,这样可以得到部分串并且使A可以几乎全部找出来

    如果串中间(非头尾)存在一块未知部分,如果是A一定会被找出来,假设前面的那个是B也不可能是C,所以一定和前面第一个已知的相同

    于是可以确定串中间的东西,剩下一个前缀以及最后一位不确定

    前缀只可能是BC,最后一位要么是A要么和n-1位相同,所以一共有四种

    判断其中三种即可,次数是(5*(1/4)+3*(1/n^2)),当n>=5时可以解决

    n=4

    考虑n=4的情况,上面的做法仍可以借鉴

    先询问AA,AB,AC,BC(没有CB),如果什么都没有找出来就是 一段C+一段B(+A) 的串,因为询问的串一定不会在未知部分出现

    那么就有(C0~4)*(A or B)+CCCC共9种,用BBB干掉BBBB,BBBA,CBBB,用CCC干掉CCCA,CCCB,CCCC,剩下三个串用两次询问解决

    次数是(4*(1/4)+2*(1/9)+2*(1/16)=1.3472<7/5)

    如果第一步找出了东西,那么最多剩下两个位置,手玩一下发现最多有6种情况,暴力判断即可,次数是(4*(1/4)+6*(1/16)=1.375)可以省掉一次但是没有必要

    code

    3.8K的交互构造题

    #include <bits/stdc++.h>
    #define fo(a,b,c) for (a=b; a<=c; a++)
    #define fd(a,b,c) for (a=b; a>=c; a--)
    #define ll long long
    using namespace std;
    
    const char b[3]={'C','H','O'};
    int T,n,m,i,j,k,l,tot;
    char a[51],A[51],c1,c2;
    bool bz;
    
    bool pd(char a,char b) {return !(a=='C' && b=='C' || a=='C' && b=='H' || a=='C' && b=='O' || a=='H' && b=='O');}
    
    int main()
    {
    	scanf("%d",&T);
    	for (;T;--T)
    	{
    		scanf("%d",&n);
    		memset(a,' ',sizeof(a));
    		
    		if (n>4)
    		{
    			printf("? CC
    ");fflush(stdout);
    			scanf("%d",&m);fo(i,1,m) scanf("%d",&j),a[j]='C',a[j+1]='C';
    			printf("? CH
    ");fflush(stdout);
    			scanf("%d",&m);fo(i,1,m) scanf("%d",&j),a[j]='C',a[j+1]='H';
    			printf("? CO
    ");fflush(stdout);
    			scanf("%d",&m);fo(i,1,m) scanf("%d",&j),a[j]='C',a[j+1]='O';
    			printf("? HO
    ");fflush(stdout);
    			scanf("%d",&m);fo(i,1,m) scanf("%d",&j),a[j]='H',a[j+1]='O';
    			printf("? OH
    ");fflush(stdout);
    			scanf("%d",&m);fo(i,1,m) scanf("%d",&j),a[j]='O',a[j+1]='H';
    			fo(i,2,n-1) if (a[i]==' ' && (a[i-1]=='H' || a[i-1]=='O')) a[i]=a[i-1];
    			
    			c1=a[1],c2=a[n];tot=bz=0;
    			fo(i,0,2)
    			if (c1==' ' && b[i]!='C' || b[i]==c1)
    			{
    				memcpy(A,a,sizeof(a));
    				fo(k,1,n-1) if (a[k]==' ') A[k]=b[i];
    				
    				fo(j,0,2)
    				if (c2==' ' && (b[j]==A[n-1] || b[j]=='C') || b[j]==c2)
    				{
    					++tot;if (tot==4) break;
    					printf("? ");
    					
    					A[n]=b[j];
    					fo(k,1,n) putchar(A[k]);
    					putchar('
    ');
    					fflush(stdout);
    					
    					scanf("%d",&m);
    					if (m) {scanf("%d",&k); memcpy(a,A,sizeof(a));bz=1;break;}
    				}
    				if (bz || tot==4) break;
    			}
    			if (tot==4) {fo(i,1,n) a[i]=(a[i]==' ')?'O':a[i];a[n]=a[n-1];}
    		}
    		else
    		{
    			printf("? CC
    ");fflush(stdout);
    			scanf("%d",&m);fo(i,1,m) scanf("%d",&j),a[j]='C',a[j+1]='C';
    			printf("? CH
    ");fflush(stdout);
    			scanf("%d",&m);fo(i,1,m) scanf("%d",&j),a[j]='C',a[j+1]='H';
    			printf("? CO
    ");fflush(stdout);
    			scanf("%d",&m);fo(i,1,m) scanf("%d",&j),a[j]='C',a[j+1]='O';
    			printf("? HO
    ");fflush(stdout);
    			scanf("%d",&m);fo(i,1,m) scanf("%d",&j),a[j]='H',a[j+1]='O';
    			fo(i,2,n-1) if (a[i]==' ' && a[i-1]=='H') a[i]=a[i-1];
    			
    			if (a[1]==' ' && a[2]==' ' && a[3]==' ' && a[4]==' ')
    			{
    				printf("? HHH
    ");fflush(stdout);
    				scanf("%d",&m);fo(i,1,m) scanf("%d",&j),a[j]=a[j+1]=a[j+2]='H';
    				printf("? OOO
    ");fflush(stdout);
    				scanf("%d",&m);fo(i,1,m) scanf("%d",&j),a[j]=a[j+1]=a[j+2]='O';
    				fo(i,2,n-1) if (a[i]==' ' && a[i-1]=='H') a[i]=a[i-1];
    			}
    			if (a[1]==' ' && a[2]==' ' && a[3]==' ' && a[4]==' ')
    			{
    				a[1]='O';a[2]='H';a[3]='H';a[4]='C';
    				printf("? ");
    				fo(i,1,n) putchar(a[i]);putchar('
    ');
    				fflush(stdout);
    				
    				scanf("%d",&m);
    				if (m) scanf("%d",&k);
    				else
    				{
    					a[1]='O';a[2]='O';a[3]='H';a[4]='H';
    					printf("? ");
    					fo(i,1,n) putchar(a[i]);putchar('
    ');
    					fflush(stdout);
    					
    					scanf("%d",&m);
    					if (m) scanf("%d",&k);
    					else
    					a[1]='O',a[2]='O',a[3]='H',a[4]='C';
    				}
    			}
    			else
    			{
    				bz=0;
    				fo(i,0,2)
    				if (a[1]==' ' || a[1]==b[i])
    				{
    					fo(j,0,2)
    					if ((a[2]==' ' || a[2]==b[j]) && (a[1]!=' ' && a[2]!=' ' || pd(b[i],b[j])))
    					{
    						fo(k,0,2)
    						if ((a[3]==' ' || a[3]==b[k]) && (a[2]!=' ' && a[3]!=' ' || pd(b[j],b[k])))
    						{
    							fo(l,0,2)
    							if ((a[4]==' ' || a[4]==b[l]) && (a[3]!=' ' && a[4]!=' ' || pd(b[k],b[l])))
    							{
    								printf("? %c%c%c%c",b[i],b[j],b[k],b[l]);putchar('
    ');
    								fflush(stdout);
    								scanf("%d",&m);
    								if (m) {a[1]=b[i],a[2]=b[j],a[3]=b[k],a[4]=b[l];scanf("%d",&k);bz=1;break;}
    							}
    							if (bz) break;
    						}
    						if (bz) break;
    					}
    					if (bz) break;
    				}
    			}
    		}
    		
    		printf("! ");
    		fo(i,1,n) putchar(a[i]);putchar('
    ');
    		fflush(stdout);
    		
    		scanf("%d",&l);
    		if (!l) return 0;
    	}
    }
    
  • 相关阅读:
    221. 最大正方形
    9. 回文数
    2. 两数相加
    1. 两数之和
    HDU 1864 最大报销额
    47 java包打成本地maven
    46 数组中的元素进行位置交换
    5 docker安装kibana
    45 vue图片放大预览
    4 docker中安装es
  • 原文地址:https://www.cnblogs.com/gmh77/p/13493561.html
Copyright © 2020-2023  润新知