numdle

算一下信息熵,每次取最大的询问。

复杂度 O(n^2),常数略大。

好像还可以组合计数,但懒得想了。

#include<iostream>
#include<vector>
#include<string>
#include<cmath>
#pragma GCC optimize("Ofast")
using namespace std;

vector<string> now;

bool multi=0;

void init(bool tag){
    now.clear();
    for(char a='0';a<='9';a++)
    for(char b='0';b<='9';b++)
    for(char c='0';c<='9';c++)
    for(char d='0';d<='9';d++){
        string x="";
        x+=a; x+=b; x+=c; x+=d;
        if(tag||(a!=b&&a!=c&&a!=d&&b!=c&&b!=d&&c!=d)) 
        	now.push_back(x);
    }
}

void check(const string &A,const string &B,int &x,int &y){
    static int b[10]; x=y=0;
    for(int i=0;i<10;i++) b[i]=0;
    for(int i=0;i<4;i++) b[A[i]-'0']++;
    for(int i=0;i<4;i++)
        if(A[i]==B[i]) x++;
        else y+=(b[B[i]-'0']>0);
}

int update(vector<string> &V,int x,int y,const string &g,bool op=0){
    if(!op){
        vector<string> w; w.clear();
        int x_,y_;
        for(string v:V){
            check(v,g,x_,y_);
            if(x_==x&&y_==y) w.push_back(v);
        }
        return V=w,0;
    }else{
        int x_,y_,ret=0;
        for(string v:V){
            check(v,g,x_,y_);
            if(x_==x&&y_==y) ret++;
        }
        return ret;
    }
}

string nq(vector<string> &V){
    double mx=0; string gu=V[0];
    int mp[5][5];
    for(string g:V){
        double e=0;
        for(int x=0;x<=4;x++)
        for(int y=0;y<=4;y++)
            mp[x][y]=update(V,x,y,g,1);
        for(string v:V){
            int x,y; check(v,g,x,y);
            if(mp[x][y]) e+=log2(1.0*V.size()/mp[x][y]);
        }
        if(e>mx) mx=e,gu=g;
    }
    return gu;
}

string Add_;

int main(){
	Point_4:
	cout<<"type : ";
	cin>>multi;
	cin.ignore();
    init(multi);
    string rq="0123";
    int x,y;
    while(now.size()!=1){
        cout<<rq<<endl;
        Point_1:
        getline(cin,Add_);
        if(Add_[0]=='F') goto Point_4;
        if(Add_[0]=='P'){
        	for(auto x:now)
        		cout<<x<<" ";
        	cout<<endl;
        	goto Point_1;
		}
		if(Add_[0]=='D'){
			printf("E=%.3lf\n",log2(now.size()));
			goto Point_1;
		}
        if(Add_[0]=='A'){
        	Point_2:
        	getline(cin,Add_);
        	if(Add_[0]=='Q')
				goto Point_3;
        	rq=Add_.substr(0,4);
        	x=Add_[5]-'0';
        	y=Add_[7]-'0';
        	update(now,x,y,rq);
        	goto Point_2;
		}
		x=Add_[0]-'0';
		y=Add_[2]-'0';
        update(now,x,y,rq);
        Point_3:
        if(now.size()==1) break;
        rq=nq(now);
    }
    cout<<rq<<"!!!"<<endl;
}
posted @ 2023-05-21 14:03  Kreap  阅读(35)  评论(0编辑  收藏  举报