uva-1262 - Password(vector的使用)

题干:

给你两个6行5列的字母表,一个整数k,两个表中第i列相同的字母可能是密码第i的字母,将所有可能性升序排列,求排完序后第k中可能性的密码是什么,如果不存在输出no。

思路:

模拟…将存储的数组按列遍历,然后存到vector中,sort排序,unique去重,然后根据后缀积,求在vector中的位置。
细节见代码

#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <string>
#include <cstring>
using namespace std;
typedef long long ll;
char a[10][10],b[10][10];
vector<char>x[10];
int ans[10],h[10];
int main()
{
	int t,n;
	//FILE *fp;  
	//fp=fopen("DATA.txt", "w");
	scanf("%d",&t);
	while(t--)
	{
		int flag=0;
		for(int i=0;i<5;i++)
			x[i].clear();
		memset(ans,0,sizeof(ans));
		memset(h,0,sizeof(h));
		scanf("%d",&n);
		for(int i=0;i<6;i++)
			scanf("%s",a[i]);
		for(int i=0;i<6;i++)
			scanf("%s",b[i]);
		for(int i=0;i<5;i++){
			for(int j=0;j<6;j++){
				for(int k=0;k<6;k++){
					if(a[j][i]==b[k][i])   //按列遍历
						x[i].push_back(a[j][i]);
				}
			}
		}
		for(int i=0;i<5;i++){
			sort(x[i].begin(),x[i].end());  //排序
			unique(x[i].begin(),x[i].end());  //去重
			if(x[i].empty())  //判断是否为空
			{
				flag=1;
				break;
			}
			while(ans[i]<x[i].size()-1&&x[i][ans[i]+1]>x[i][ans[i]]) //因为unique去重是将重复的变成不重复的
				ans[i]++;
			ans[i]++;  //因为至少一个
			//printf("%d\n",ans[i]);
		}
		if(flag)  //判断vector数组是否为空,注意这一点
		{
			printf("NO\n");
			continue;
		}
		h[5]=1;
		for(int i=4;i>=0;i--){
			h[i]=1;
			h[i]=ans[i]*h[i+1];  //求后缀积
		}
		if(n>h[0]) //判断是否超限
			printf("NO\n");
		else{
			n--;
			for(int i=0;i<5;i++){
				printf("%c",x[i][n/h[i+1]]);  //求位置
				n%=h[i+1];
			} 
			printf("\n");
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_42279796/article/details/89387659