6.23 d2 2、3、4题

2、Tavan


描述
小 Zeljko  一直在阁楼里读他奶奶的旧信, 并且发现了一个长度为 N  的单词 。
不幸的是,由于溢出的墨水,他不知道单词的内容。他把看不清的 M  个字母每个字母都用一个字符'#' 替换后,在一张纸上重写了这个词。他把那张纸递给了他的奶奶 , 对于每个看不清的字母 , 奶奶给了他 K 个不同的可能 。 在那之后 ,Zeljko  在笔记本中写下了所有可能的单词,并决定仔细查看他们的属性,以确定原始单词是什么。在看到笔记本上写下的单词后,他的奶奶意识到他们正在
寻找的是按字典序排列的第 X 个单词。Zeljko  在他们学校学习字母表的那天生
病了,所以他要求你帮助他确定原来的单词。
输入
第一行输入包含整数 N,M ,K 和 X (1 ≤N ≤ 500,1 ≤ M ≤N ,1 ≤K ≤ 26,1 ≤X ≤10^{9})。分别表示单词的长度,看不清的字母数量,奶奶给出的字母的数量和原单词是字典序的第几个。
第二行输入包含一个长度为 N  的字符串,由小写英文字母和字符' #' 组成 。
表示 Zeljko  找到的单词,其中字符'#' 表示看不清的字母。
接下来 M 行中的每一行包含一个长度为 K  的字符串, 由 K 个不同的小写英文
字母组成。第 2+i  行的 K  个字母表示第 i i  个看不清的字母的K种可能。
保证 X 总是小于等于能构造出的单词的总数。
输出
输出一个字符串。表示原本的单词。
分数分布
对于  30% 的数据,M=1  并且  K=3 。
对于另外  30% 的数据, M=1 。
样例输入 1
9 2 3 7
po#olje#i
sol
znu
样例输出 1
posoljeni
样例输入 2
4 1 2 2
#rak
zm
样例输出 2
zrak

思路

之前用类似于递归的方法做错了只得了60分,后来改的时候就用循环代替实现

其实就是以k值和m值为基础的方案数的寻找

错误代码(又臭又长又耗时还错)

#include
#include
#include
#include
#include
using namespace std;
#define MAXN 501
int n,m,k,x,t;
long long p[MAXN]={1};
char c[MAXN],s[MAXN][27],w[MAXN];
bool cmp(char a,char b)
{
	return int(a)m)return;
	for(int i=0;i

正确代码

#include
#include
#include
#include
#include
using namespace std;
#define MAXN 501
int n,m,k,x;
char c[MAXN],s[MAXN][27],w[MAXN];
int main()
{
	freopen("tavan.in","r",stdin);
	freopen("tavan.out","w",stdout);
	scanf("%d%d%d%d",&n,&m,&k,&x);
	scanf("%s",c+1);
	for(int i=1;i<=m;i++)
	{
		scanf("%s",s[i]);
		sort(s[i],s[i]+k);
	}
	x--;//s序号从0开始
	for(int i=n,j=m;i>=1;i--)//倒着除从最后往前找
		if(c[i]=='#')
		{
			c[i]=s[j][x%k];//找到每层对应的序数
			x/=k;
			j--;
		}
	printf("%s",c+1);
}

3、Nizin

描述 Do Geese See  God ?或者,Was It  A Rat I Saw ?没关系,这只是展示  Mislav 
对回文的热爱的不必要的介绍。帮他解决以下任务!设 A 是 N  个整数构成的数组 。 我们说 A  是回文 , 如果  A[i]=A[N-i+1] 对于每个 i 都成立,其中  A[i] 表示数组 A  的第 i  个元素,并且数组中的第一个元素编号是 1 。
Mislav  可以通过以下方式修改数组:在一次操作中,他选择该数组的两个
相邻元素并用它们的和替换它们。注意, 每次操作后数组中元素的数量将减少 1。
Mislav  想知道为了让数组变为回文的,他必须做出最少多少次操作。
输入
第一行输入包含整数 N (1 ≤N ≤ 10^{6}),表示数组中的元素个数。
第二行输入包含 N 个用空格分隔的正整数,表示 Mislav  数组中的元素。数
组中的数字最多为10^{9}
输出
输出一个整数。表示  Mislav  要把数组变为回文所需的最少操作次数。
分数分布
对于  30% 的数据, N ≤ 10 。
对于  60% 的数据, N ≤ 1000 。
样例输入 1
3
1 2 3
样例输出 1
1
样例输入 2
5
1 2 4 6 1
样例输出 2
1
样例输入 2
4
1 4 3 2
样例输出 2
2

思路

这道题过得蛮顺的,就从两端开始相等不变,小的加,最后大不了成一个数

代码

#include
#define MAXN 1000001
int n,ans;
int a[MAXN];
void wow(int s,int e)
{
	if((s+1==e||s+2==e)&&a[s]==a[e])return;//中间有一个数也没关系
	if(s==e)return;//这个就证明加到一块了
	if(a[s]==a[e])
	{
		wow(s+1,e-1);
		return;
	}
	else
	{
		if(a[s]

4、Prosjecni


描述

 Slavko  很无聊,所以他把正整数填到 N*N  的方阵中。
如果他填出来的方阵满足以下条件,他会特别高兴:
● 每行中的数字的平均值是一个位于同一行的整数。
● 每列中的数字的平均值是一个位于同一列的整数。
● 表中的所有数字都不同。
帮助 Slavko  找到一种会让他开心的填法。
输入
第一行输入包含整数 N (1 ≤N ≤ 100 )。表示方阵的行数和列数。
输出
输出 N行,每行输出 N 个由空格分隔的整数 . 令第 i行中的第 j 个数字对应
于Slavko  将在方阵的第 i 行第 j列写下的值。
所有数字必须大于 0 且小于10^{9}
如果有多个解决方案,则输出任意一个。
如果没有任何解决方案,则输出 -1 。
分数分布
无特殊分数分布。
样例输入 1
3
样例输出 1
1 2 3
4 5 6
7 8 9
样例输入 2
2
样例输出 2
-1

思路

这道题我一开始想的就是找规律,可是规律找错了(>﹏<)

没关系,正确规律是:

1、当n=2时,无解

2、当n为奇数时,直接1~n*n输出

3、当n为偶数时,1行的最后一个n*(n-1)/2,1~n-1行在上一行的基础上+n*(n-1)/2,最后一行以每一列的最后一个为平均数求最后一行的数

代码

#include
int n;
int a[101][101];
int main()
{
	freopen("prosjecni.in","r",stdin);
	freopen("prosjecni.out","w",stdout);
	scanf("%d",&n);
	if(n==2)
		printf("-1");
	else
	{
		if(n%2==1)
		{
			int x=1;
			for(int i=1;i<=n;i++)
			{
				for(int j=1;j

 

你可能感兴趣的:(中考暑假记)