NEUQ2022ACM招新赛题解

7-1 Win

 简单的字符串比较。

#include<bits/stdc++.h>
using namespace std;
string a; 
int main()
{
	cin>>a;
	if(a=="NEU") printf("Win");
	else if(a=="THU") printf("Lose");
	else printf("?");
	return 0;
}

7-2 比大小

由题意知比法与字典序相像,只需将数字以字符串读入并用strcmp()比较即可。

#include<bits/stdc++.h>
using namespace std;
int T;
int main()
{
	scanf("%d",&T);
	while(T--)
	{
		string a,b;
		cin>>a>>b;
		int k=strcmp(&a[0],&b[0]);
		if(k>0) printf(">\n");
		else if(k==0) printf("=\n");
		else printf("<\n");
	}
	return 0;
}

7-3 矩阵乘法

按题意模拟即可。三层循环,最内层算答案。

#include<bits/stdc++.h>
using namespace std;
int a[110][110],b[110][110];
int main()
{
	int n,p,m;
	scanf("%d%d%d",&n,&p,&m);
	for(int i=1;i<=n;++i)
		for(int j=1;j<=p;++j)
			scanf("%d",&a[i][j]);
	for(int i=1;i<=p;++i)
		for(int j=1;j<=m;++j)
			scanf("%d",&b[i][j]);
	for(int i=1;i<=n;++i)
	{
		
		for(int j=1;j<=m;++j)
		{
			int sum=0;//计算结果
			for(int k=1;k<=p;++k)
			{
				sum+=a[i][k]*b[k][j];
			}
			printf("%d ",sum);
		}
		printf("\n");
	}
	return 0;
}

 7-4 疯狂星期四

 计算两个日期相隔天数以此推星期几。

题目给出2022年10月11日是星期二,由于在此前此后计算日期方式不同,我们可先计算出1/1/1是星期一,再由此做计算。

星期数=(1+day%7)%7;day为相距天数

#include<bits/stdc++.h>
using namespace std;
int runnian[13]={0,31,29,31,30,31,30,31,31,30,31,30,31};
int pingnian[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int p(int y)
{
	if((y%4==0&&y%100!=0)||y%400==0) return 1;//闰年
	else return 0;//平年
}
int main()
{
	int y=1,m=1;
	int day=0;
	int y1,m1,d1;
	scanf("%d%d%d",&m1,&d1,&y1);
	while(y<y1)//计算年
	{
		if(p(y)) day+=366;
		else day+=365;
		++y;
	}
	while(m<m1)//月
	{
		if(p(y)) day+=runnian[m];
		else day+=pingnian[m];
		++m;
	}
	day+=d1-1;//日
	int ans=1+day%7;
	ans%=7;
	printf("%d",ans);
	return 0;
}

7-5 排列

重在理解题意:选定一个长度为k的区间,将这段区间里的数全都转化为区间最大值。

那么直接从包含整个序列中最大的数开始覆盖即可。

由于覆盖时要包括最大数本身,则一次覆盖k-1个数,而一共有n-1个待覆盖数。

分析可得,序列排序并不影响结果,则

ans=\left \lceil \frac{n-1}{k-1} \right \rceil

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int n,k;
	scanf("%d%d",&n,&k);
	int ans=(n-1)/(k-1);
	if((n-1)%(k-1)) ans+=1;
	printf("%d",ans);
	return 0;
}

7-6 小步点

dfs遍历

#include<bits/stdc++.h>
using namespace std;
int v[10];
int a[10],b[10];
double d=0,ans=1e9;
void dfs(int st,int dep)//st起始点,dep深度
{
	for(int i=1;i<=5;++i)
	{
		if(!v[i])
		{
			v[i]=1;
			int k=pow(a[st]-a[i],2)+pow(b[st]-b[i],2);
			d+=sqrt(k);//距离
			dfs(i,dep+1);
			v[i]=0;
			d-=sqrt(k);//消除影响
		}
	}
	if(dep==5) ans=min(ans,d);//统计
	
}
int main()
{
	for(int i=1;i<=5;++i)
	{
		scanf("%d%d",&a[i],&b[i]);
	}
	for(int i=1;i<=5;++i)
	{
		v[i]=1;
		dfs(i,1);
		v[i]=0;
	}
	printf("%.3lf",ans);
	return 0;
}

7-7 原神生日会

        由于男女间隔,一男一女排列最小单元是两人,设空位数为n,则:

        1.n%2==0,男女都坐n/2人。

        2.n%2==1,男女先坐n/2人,剩下一人可男可女。

#include<bits/stdc++.h>
using namespace std;
char c;
int h[1000000];
int main()
{
	int n,a,b;
	scanf("%d%d%d",&n,&a,&b);
	int a1=0,b1=0;
	int top=1;
	int k=0;
	getchar();//读入换行符
	while(n--)
	{
		scanf("%c",&c);
		if(c=='.') ++h[top];
		else if(h[top]!=0) ++top;
	}//统计,共top个区间,区间中有h[i]个位置
	int cnt=0;
	for(int i=1;i<=top;++i)
	{
		a1+=h[i]/2;b1+=h[i]/2;
		if(h[i]%2!=0)
		{
			++cnt;//可男可女的个数
		}
	}
	int ans=0;
	for(int i=0;i<=cnt;++i)
	{
		ans=max(ans,min(a1+i,a)+min(b1+cnt-i,b));
        //将cnt分配出去,找到最优解
	}
	printf("%d",ans);
	return 0;
}

7-8 漏字文

        找缺失某一或某几个字母的最长连续单词的字母数。

        从开始向后统计,遇到26字母都有时,依次减去统计区间的第一个单词,直到26字母不够时,再向后统计新单词,期间不断更新答案。

#include<bits/stdc++.h>
using namespace std;
string a[100010];
int zmb[30];//统计各字母个数
int l[100010];
int main()
{
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;++i)
	{
		cin>>a[i];
		l[i]=a[i].length();
	}
	int cnt=0;//统计使用字母种类 
	int k=1;//初始开始区间
	int sum=0;//实时字母数
	int ans=0;
	for(int i=1;i<=n;++i)
	{
		for(int j=0;j<l[i];++j)//录入新单词 
		{
			if(zmb[a[i][j]-'a']==0) ++cnt;//使用字母数 
			zmb[a[i][j]-'a']++;
		}
		sum+=l[i];
		while(cnt==26)//全用过了。减去开头单词 
		{
			for(int j=0;j<l[k];++j)
			{
				zmb[a[k][j]-'a']--;
				if(zmb[a[k][j]-'a']==0) --cnt;
			}
			sum-=l[k];
			++k;
		}
		ans=max(ans,sum);//更新答案
	}
	printf("%d",ans);
	return 0;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值