“九韶杯”河科院程序设计协会第一届程序设计竞赛 【前六题解析】

https://ac.nowcoder.com/acm/contest/13493#rank

目录

  • A: 6的个数
  • B: 小明的作业
  • C: 斐波那契
  • D: 数列重组
  • E: 三角形个数
  • F: 字符串

A: 6的个数

“九韶杯”河科院程序设计协会第一届程序设计竞赛 【前六题解析】_第1张图片
https://ac.nowcoder.com/acm/contest/13493/A
签到题

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
int sum=0;
using namespace std;
int main(void)
{
     
	for(int i=0;i<=2021;i++)
	{
     
		int temp=i;
		while(temp)
		{
     
			int t=temp%10;
			if(t==6) sum++;
			temp/=10;
		}
	}
	cout<<sum<<endl;
	return 0;
} 

B: 小明的作业

“九韶杯”河科院程序设计协会第一届程序设计竞赛 【前六题解析】_第2张图片
https://ac.nowcoder.com/acm/contest/13493/B
唉,数的时候加错了,算成了68 25
正确答案是 78 和 25。
大致思路就是: 将wa转换成一个特殊的符号。aw也转换成一个特殊的符号 ;例如 &&
将其他的字符弄成空格。看输出的挨个数,&&是警告 长的例如&&&&就是错误的。

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
string a;
int sum1,sum2;
int main(void)
{
     
	/*cin>>a;
	cout<
	cout<<78<<endl;
	cout<<25<<endl; 
	return 0;
} 

“九韶杯”河科院程序设计协会第一届程序设计竞赛 【前六题解析】_第3张图片
文件操作:
我上面的那种毕竟需要手数。不是纯编程的,那么我想了一下纯编程的。
才发现好麻烦。

文件操作有一个大坑,记住不要用笔记本的替换字符功能,太坑了。

“九韶杯”河科院程序设计协会第一届程序设计竞赛 【前六题解析】_第4张图片
“九韶杯”河科院程序设计协会第一届程序设计竞赛 【前六题解析】_第5张图片
大致思路就是,还是上面的处理操作。不过把输出的内容输出到一个文本。
我们从文本里读取处理后的字符串,统计个数。

处理字符的时候注意: wa 和 aw的变换字符要不相同。不然会问题。

:  wawaaw
要处理为 &&&&**  要统一处理的话就是 &&&&&&  统计的结果明显是不同的
#include
#include
#include
#include
using namespace std;
string a;
int sum1;
int sum2;
int main(void)
{
     
	/*cin>>a;//处理字符串
	for(int i=0;i+1
	freopen("1.txt","r",stdin);//从文件中读取 统计个数
	getline(cin,a);
	int count1=0;//看读取了几个字符
	int count2=0;//卡读取了几个字符
	bool flag1=false;//判断读取到了
	bool flag2=false;//判断读取到了特殊字符
	for(int i=0;i<a.size();i++)
	{
     
		if(a[i]=='&')//读取到了特殊字符
		{
     
			count1++;//计数加一
			flag1=true;//判断开始
			continue;
		}
		if(flag1&&a[i]!='&')//说明是&开头的字符,且这一串的&已经读取完了
		{
     
			if(count1>2) sum2++;//说明是一个连着的字符
			else sum1++;//说明是单个的字符
			count1=0;
			flag1=false;
		}
		if(a[i]=='*')
		{
     
			count2++;
			flag2=true;
			continue;
		}
		if(flag2&&a[i]!='*')
		{
     
			if(count2>2) sum2++;
			else sum1++;
			count2=0;
			flag2=false;
		}
	}
	cout<<sum1<<endl;
	cout<<sum2<<endl;
	return 0;
}

“九韶杯”河科院程序设计协会第一届程序设计竞赛 【前六题解析】_第6张图片
还是第一种香,方便。第二种容易出错。

C: 斐波那契

“九韶杯”河科院程序设计协会第一届程序设计竞赛 【前六题解析】_第7张图片
https://ac.nowcoder.com/acm/contest/13493/C
关键点: 在计算的时候要记得求分子和分母的最大共约数约分,不要会爆long long
我计算的时候是先打表 斐波那契前20项
再打表分母前13项。一边看一下有没有出错。
一边看一下,会不会爆long long 。
大致看了一下,一定会爆的。那么我们在每次两数相加的时候,通分一下就好了(即分子和分母同时除以两者的最大共约数)。

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
int a[20]={
     0,1,1};
int b[20];
long long int s1;
long long int s2;
long long int gcd(long long int a,long long int b)
{
     
	if(b==0) return a;
	return gcd(b,a%b);
}
int main(void)
{
     
	for(int i=3;i<=18;i++)//斐波那契数列 
	{
     
		a[i]=a[i-1]+a[i-2];
	}
	for(int i=1;i<=13;i++)
	{
     
		b[i]=a[i]*a[i+1];//分母 
	}
	s1=1;//分子 
	s2=1;//分母 
	for(int i=2;i<=13;i++)
	{
     
		s1=s1*b[i]+1*s2;
		s2=s2*b[i];
		long long int temp=gcd(s1,s2);//两者的最大共约数 
		s1=s1/temp;//通分 
		s2=s2/temp;//通分 
	} 
	cout<<s1<<"/"<<s2<<endl;
	//cout<<6535086616739<<"/"<<3684083162760<
	return 0;
} 

D: 数列重组

“九韶杯”河科院程序设计协会第一届程序设计竞赛 【前六题解析】_第8张图片
https://ac.nowcoder.com/acm/contest/13493/D
注意: 题目问的是有几种排列的方式。是全列列中,看有没有满足条件的。
我最开始以为是全排列后,再分不同的堆,不同的分法是不同种。好吧眼瞎了没有看提示。
本题用is_sort()函数及其的方便。感兴趣的可以搜一搜具体的用法。

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
int a[10]={
     2,5,3,6,3,6,7,3,7,8};
int ans;
int sum=0;
bool cmp(int a,int b)
{
     
	return a>b;
}
int main(void)
{
     
	sort(a,a+10);
	bool flag;
	do
	{
     
		flag=false;
		for(int i=0;i<8;i++)
		{
     	
			for(int j=i+1;j<9;j++)
			{
     
				
				if( ( is_sorted(a,a+i+1) || is_sorted(a,a+i+1,cmp) )
				&& ( is_sorted(a+i+1,a+j+1)||is_sorted(a+i+1,a+j+1,cmp) )
				&& ( is_sorted(a+j+1,a+10)||is_sorted(a+j+1,a+10,cmp) ) ) 
				{
     
					flag=true;
					break;
				}
			}
			if(flag)
				break;
		}
		if(flag)
			ans++;
	}while(next_permutation(a,a+10));
	cout<<ans<<endl;
	return 0;
} 

E: 三角形个数

“九韶杯”河科院程序设计协会第一届程序设计竞赛 【前六题解析】_第9张图片
https://ac.nowcoder.com/acm/contest/13493/E
数学问题,找规律,推出公式。

官方题解是这样的:
“九韶杯”河科院程序设计协会第一届程序设计竞赛 【前六题解析】_第10张图片
套公式看一下规律:
“九韶杯”河科院程序设计协会第一届程序设计竞赛 【前六题解析】_第11张图片
其实这个道题的大致思路:
就是看 从1~n边长的所有的 正着的三角形的个数和倒着的三角形的个数之和。
说实话,这规律我觉得不容易推,何况考试的时候紧张和慌不好找,建议记住大致的公式模板。
“九韶杯”河科院程序设计协会第一届程序设计竞赛 【前六题解析】_第12张图片

#include
#include
#define ll long long 
using namespace std;
ll ans=0;
ll m=1e9+7;
int main(void)
{
     	
	ll n=20210411;
	for(int i=1;i<=n;i++)
	{
     
		 ll a=(n-i+2)*(n-i+1)/2%m;//正三角型个数 
		 if((n-2*i+1)>0) a=(a+(n-2*i+1)*(n-2*i+2)/2)%m;//倒着的三角形个数 
		 ans=(ans+a)%m;
	}
	cout<<ans<<endl;
	return 0;
} 

F: 字符串

“九韶杯”河科院程序设计协会第一届程序设计竞赛 【前六题解析】_第13张图片
https://ac.nowcoder.com/acm/contest/13493/F
挺简单的,不过考完后看了一下自己AC的代码,感觉写的真的垃圾。

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
int n;
string a[10005];
string str;
string cmp="@wyk";
int ans;
int main(void)
{
     
	scanf("%d",&n);
	getline(cin,str);
	for(int i=0;i<n;i++)
	{
     
		getline(cin,a[i]);
	}
	
	for(int i=0;i<n;i++)
	{
     
		for(int j=0;j<a[i].size();j++)
		{
     
			bool flag=false;
			if(a[i][j]=='@')
			{
     
				int k=j+1;
				int w;
				for(w=1;w<=3;w++)
				{
     
					if(a[i][k++]!=cmp[w])
						break;
				}
				if(w==4)
				{
     
					flag=true;
				}
			}
			if(flag)
			{
     
				ans++;
				break;
			}
		}
	}
	cout<<ans;
	return 0;
} 

复盘的时候,一想 直接用string的find()函数它不爽么?

#include
#include
#include
#include
using namespace std;
const int N=10010; 
int n;
int ans;
string str[N];
string s="@wyk";
int main(void)
{
     
	cin>>n;
	char a=getchar();
	for(int i=0;i<n;i++) getline(cin,str[i]);
	for(int i=0;i<n;i++)
	{
     
		if(str[i].find(s)!=string::npos)
			ans++; 
	}
	cout<<ans<<endl;
	return 0;
} 

其实可以一边输入,一边统计

#include
#include
#include
#include
using namespace std;
int n;
int ans;
string str;
string s="@wyk";
int main(void)
{
     
	cin>>n;
	char a=getchar();
	for(int i=0;i<n;i++) 
	{
     
		getline(cin,str);
		if(str.find(s)!=string::npos)
			ans++; 
	}	
	cout<<ans<<endl;
	return 0;
} 

官方题解也不错

#include 
#include 
#include 

using namespace std;


int main(){
     
	int ans=0,n;
	cin>>n;
	getchar();
	for(int i=0;i<n;i++){
     
		string s;
		getline(cin,s);
		for(int j=0;j<s.size();j++){
     
			if(s[j]=='@'){
     
				if(s.substr(j,4)=="@wyk"){
     
					ans++;
					break;
				}
			}
		}
	}
	cout<<ans<<endl;
	return 0;
}

你可能感兴趣的:(编程比赛,c++,程序设计,算法)