前五题题解+更好的交换详解(分析大部分为后面的题目)

long loong

此题是一个水题,输入一个数x,并在特定的两串字符间输出x个o,我们很自然的想到先输出前面的L再通过for循环或者while等循环输出x个o,再输出后面的ng,代码如下

#include<iostream>
using namespace std;
int main()
{
	int n;
	cin>>n;
	cout<<"L";
	for(int i=1;i<=n;i++)
	{
		cout<<"o";
	}
	cout<<"ng";
}

YES or YES?问题

看到此题的第一个想法就是暴力解题,只要条件写的全,答案马上现,也是水题,代码奉上

#include<iostream>
using namespace std;
int main()
{
	int n,ans=0;
	string s;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>s[1]>>s[2]>>s[3];
		ans=0;
		if(s[1]=='y'||s[1]=='Y')ans++;
		if(s[2]=='E'||s[2]=='e')ans++;
		if(s[3]=='S'||s[3]=='s')ans++;
		if(ans==3)cout<<"YES"<<endl;
		else
		{
			cout<<"NO"<<endl;
		}
	}
}

小结:只要肯列条件总有答案的

Even? Odd?重点讨论分析

从题干我们可以看到此题为判断奇偶数,按照正常思维,我们只要将数求余二即可判断,代码如下

#include<iostream>
using namespace std;
int main()
{
	long long n,x;
	string s;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>x;
		if(x%2==0||x==0)cout<<"even"<<endl;
		if(x%2!=0)cout<<"odd"<<endl;
	}
}

我们提交之后发现部分错误,这时我们就会发现题目藏了一个大坑,这可坑死我这个蒟蒻了,从题中可以发现数据范围:每个正整数不超过 10的60次方,这已经远远大于long long的长度了,并且整型里没有数据类型可以适配,此时我们就必须换一种思路了

通过数学知识我们知道判断一个数的奇偶性之需要判断这个数的个位数是否是2的倍数或者是否是零,为了保证数据不溢出,我们不能选择所有的数的类型,此时就只剩下一条路了——字符。

是不是突然豁然开朗了,我们只需要将数据用字符数组表示就可以轻松容下,并且数组只要开到大于六十即可,我们再用strlen函数获取数据的长度即可获得最后一位数所在的位置,再用最后一位数求余二即可完美解决啦,最后代码奉上

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int main()
{
    int n,i,len;
    char c[65];
    cin>>n;
    for(i=1;i<=n;i++)
    {
        cin>>c;
        len=strlen(c);
        if((c[len-1]-'0')%2==0)
            cout<<"even\n";
        else
            cout<<"odd\n";
    }
    return 0;                   
}

当数据表示的数字过大时,不妨尝试用字符数组来表示

Problem Generator问题(两种解法)

题目要求有七个难度维度ABCDEFG,每个难度维度的题都至少要m个,然后求最少要加几道题才能达成,显然,当我们仅将少于m个难度维度的题补至m个时加的题目最少,所以我们此题的解题思路就很明晰了,先计算每个维度题目的数量并于m比较,找出少于m的难度维度,我们再将其补齐即可(即用m*7-m*数量达标维度-不达标维度的题数)。注意此题存坑,众蒟蒻小心,在解法二中指出

解法一:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int main()
{
	int n,x,y;
	char s;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		int a[8]={0,0,0,0,0,0,0,0};
		cin>>x>>y;
		for(int j=1;j<=x;j++)
		{
			cin>>s;
			if(s=='A')a[1]++;
			if(s=='B')a[2]++;
			if(s=='C')a[3]++;
			if(s=='D')a[4]++;
			if(s=='E')a[5]++;
			if(s=='F')a[6]++;
			if(s=='G')a[7]++;
		}
		if(a[1]>=y)a[1]=y;
		if(a[2]>=y)a[2]=y;
		if(a[3]>=y)a[3]=y;
		if(a[4]>=y)a[4]=y;
		if(a[5]>=y)a[5]=y;
		if(a[6]>=y)a[6]=y;
		if(a[7]>=y)a[7]=y;
		int ans=7*y-(a[1]+a[2]+a[3]+a[4]+a[5]+a[6]+a[7]);
		cout<<ans<<endl;
	}                
}

解法二

#include<stdio.h>
int main()
{
	int t,n,m,sum=0,j,a[7]={0};
	char c;
	scanf("%d",&t);
	for(int i=0;i<t;i++)
	{
		scanf("%d %d",&n,&m);
		for(j=0;j<n;j++)
		{
			scanf("%c",&c);
			if(c=='\n')scanf("%c",&c);
			a[c-65]++;
		}
		sum=0;
		for(j=0;j<7;j++)
		{
			if(a[j]<m)
			sum+=m-a[j];
		}
		printf("%d\n",sum);
		for(j=0;j<7;j++)
		{
			a[j]=0;
		}
		sum=0;
	}
	return 0;
}

注:部分人员在进行数据输入时忽视换行符对数据输入的影响,将导致数据输入数量错误。

rules问题

秉持大问题变成多个小问题的原则,我们可以首先将问题分解为某天内是否有大于等于一半的人遵守了规则 k,再计算是否在大于等于一半的天数里,规则 k符合民意,代码奉上

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int main()
{
	int n,m,k,x;
	cin>>n>>m>>k;
	int ans=0;
	for(int i=1;i<=m;i++)
	{
		int count=0;
		for(int j=1;j<=n;j++)
		{
			cin>>x;
			if(x==k)count++;
		}
		if(count*2>=n)ans++;
	}
    if(ans*2>=m)cout<<"YES";
	else
	{
		cout<<"NO";
	}          
}

小结:化繁为简,四两拨千斤

最后一题也是我觉得最值得多练习的一题

更好的交换(重点分析)

先讲讲大众思路,先建立一个二维数组保存题目所给的数据,每当输入一个数据指令,对二维数组中的数据进行变化,所有数据输入完后输出最后的二维数组,代码如下

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int m,n,b=0;
	cin>>m>>n;
	int a[1000][1000];
	for(int i=1;i<=m;i++)
		for(int j=1;j<=m;j++)
			cin>>a[j][i];
	for(int i=1;i<=n;i++){
		int k,x,y;
		cin>>k>>x>>y;
		if(k==1){
			for(int p=1;p<=m;p++) {
				b=a[p][x];
				a[p][x]=a[p][y];
				a[p][y]=b;
			}
		}
		if(k==0){
			for(int p=1;p<=m;p++) {
				b=a[x][p];
				a[x][p]=a[y][p];
				a[y][p]=b;
			}
		}
		b=0;
	}
	for(int i=1;i<=m;i++){
		for(int j=1;j<=m;j++)cout<<a[j][i]<<" ";
		cout<<endl;
	}
}

 代码一路顺畅的写下来,看似没有问题,逻辑完全说的通,但可惜的是最终之拿到了60分,

那还有的四十分怎么丢的呢,这就是出题人的小心思了,给了较大的数据量和严格的运行时间限制,此时怎么办呢,经观察,我们会发现这个矩阵型的数据行变换和列变换相互之间是没有影响的,所以我们可以用两个数组分别表示行向量和列向量,行列变换同时可进行,大大减少运行的时间复杂度,代码如下

#include<bits/stdc++.h>
using namespace std;
int a[500000],b[500000],mp[5000][5000];
int main()
{
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		a[i]=i,b[i]=i;
		for(int j=1;j<=n;j++)
		{
			cin>>mp[i][j];
		}
	}
	for(int i=1;i<=m;i++)
	{
		int op,x,y;
		cin>>op>>x>>y;
		if(op)
		{
			int t=a[y];
			a[y]=a[x];
			a[x]=t;
		}
		else
		{
			int t=b[y];
			b[y]=b[x];
			b[x]=t;
		}
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			cout<<mp[a[i]][b[j]]<<" ";
		}
		cout<<endl;
	}
}

完结撒花!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值