1 条题解

  • 0
    @ 2026-9-25 1:42:44

    好题。

    1.思路

    看到题目发现密码只有四位,考虑枚举密码。
    注意到直接按位枚举密码会 T 飞。
    不难想到前缀和优化。

    首先,先统计每位后首个每种密码的位置。
    这里需倒着枚举一下。
    核心代码如下:

    //p[i][j]第i位及之后首个j的位置。  
    if(j==s[i]-'0')p[i][j]=i;//若该位为j则它最前。   
    else p[i][j]=p[i+1][j];//否则它继承后一位。  
    

    统计完之后,检验每个答案。
    来个四层嵌套循环枚举每一位。
    按照操作顺序,依次找最前的位置。
    如果超出操作数量说明不存在。
    写出来是这样。

    for(i=0;i<10;i++)for(j=0;j<10;j++)for(k=0;k<10;k++)for(x=0;x<10;x++)if(p[p[p[p[0][i]][j]][k]][x]>=t)g[i*1000+j*100+k*10+x]=1;
    

    剩下的就是疯狂调试环节。
    如果您是来观赏我丑陋的代码的,那么以下是为您准备的:

    2.代码

    :::::::::warning[不要试图贺代码]
    人要有素质。 :::::::::

    #include<bits/stdc++.h>
    using namespace std;
    string s,emp;
    int p[100005][10],ans,n,t,i,j,k,x;
    //p[i][j]第i位之前首个j的位置。
    bool g[10005];
    void CaO(){//氧化钙,检查答案的好帮手。
    	for(i=0;i<10;i++)for(j=0;j<10;j++)for(k=0;k<10;k++)for(x=0;x<10;x++)if(p[p[p[p[0][i]][j]][k]][x]>=t)g[i*1000+j*100+k*10+x]=1;
    	//这里有点长,后面那一大坨表示如能实现答案的位置,>=j+1就不行。如果不满足便标记一下。 
    	return ;
    } 
    int main(){
    	ios::sync_with_stdio(0);
    	cin.tie(0); 
    	cin>>n;
    	return 0;
    	while(n--){
    		cin>>t>>s;
    		for(j=0;j<10;j++)p[t][j]=t;
    		//别忘记初始化喵
    		for(i=t-1;i>=0;i--){
    			for(j=0;j<10;j++){
    				if(j==s[i]-'0')p[i][j]=i;//若该位为j则它最前。 
    				else p[i][j]=p[i+1][j];//否则它继承后一位。 
    				//cout<<i<<' '<<j<<' '<<p[i][j]<<endl;
    			}
    		}
    		CaO();
            s=emp;
    	}
    	for(i=0;i<10000;i++)if(!g[i])ans++;//,cout<<i<<endl;
    	cout<<ans<<endl;
    	return 0;//下班收工! 
    }
    
    • 1

    信息

    ID
    3181
    时间
    1000ms
    内存
    128MiB
    难度
    10
    标签
    递交数
    2
    已通过
    1
    上传者