哈尔滨理工大学软件与微电子学院程序设计竞赛(同步赛)A~Q

晚自习玩了一下哈理工新生赛,发现自己还是太弱了啊啊啊
今天补了一些题目,不过因为考试在急就没补完(其实是由于太菜连题解也看不懂!)
有些题目请教了fjy和ph两位大佬,非常感谢两位大佬对我这个蒟蒻的指点%%%
代码风格可能比较烂,而且解法并不是最优秀的,希望大家包容。不正确的地方可以评论区评论一下awa
前10题考试题不做详述(E题可以康康)
A

#include<bits/stdc++.h>
using namespace std;

int main()
{
    
    
	printf("V     V\n");
	printf(" V   V\n");
	printf("  V V\n");
	printf("   V\n");
	return 0;
}

B

#include<bits/stdc++.h>
using namespace std;

int main()
{
    
    
	double a,b;
	cin>>a>>b;
	printf("%.3lf",b/a*100);
	printf("%");
	return 0;
}

C

#include<bits/stdc++.h>
using namespace std;

int main()
{
    
    
	int m,n;
	cin>>m>>n;
	if(m%n==0)printf("YES");
	else printf("NO");
	return 0;
}

D

#include<bits/stdc++.h>
using namespace std;

int main()
{
    
    
	int m,n;
	int h1,m1,h2,m2,h3=0,m3=0;
	cin>>h1>>m1>>h2>>m2;
	if(m1>m2)
	{
    
    
		h3=-1;
		m2+=60;
	}
	h3+=h2-h1;
	m3=m2-m1;
	cout<<h3<<" "<<m3;
	return 0;
}

E
个人觉得字符串处理方便一些,主要是看数字出现频率
这里用了map,大家也可以用桶排序(参考I题)实现排序+统计数量的操作(不过要注意数量都是0的情况)

#include<bits/stdc++.h>
using namespace std;

map<char,int>ma,mb;
int main()
{
    
    
	string a,b;
	cin>>a>>b;
	for(int i=0;a[i];i++)ma[a[i]]++;
	for(int i=0;b[i];i++)mb[b[i]]++;
	if(a==b)cout<<100;
	else
	{
    
    
		int flag=1,cnt=0;
		for(char i='0';i<='9';i++)
		{
    
    
			//cout<<i<<" "<<ma[i]<<" "<<mb[i]<<endl;
			if(ma[i]==mb[i]&&ma[i]>0&&mb[i]>0)cnt++;
			else if(ma[i]!=mb[i])flag=0;
		}
		if(flag)cout<<20;
		else if(flag==0&&cnt>0)cout<<2;
		else if(flag==0&&cnt==0)cout<<0;
	}
	return 0;
}

F

#include<bits/stdc++.h>
using namespace std;

int main()
{
    
    
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
	cout<<"China will win the battle against COVID-19."<<endl;
	return 0;
}

G

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int a[N];
int main()
{
    
    
	double n,sum=0.0;
	int maxn=-100,minn=200;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
    
    
		cin>>a[i];
		sum+=a[i];
		if(a[i]>maxn)maxn=a[i];
		if(a[i]<minn)minn=a[i];	
		}
	printf("%.2lf %d %d",sum/n,maxn,minn);
	return 0;
}

H
这可能是前10题里我做得最丢人的一题了,写了n*n方阵反复调了五六次,这类题打印图形的题目可以自己画几个找找规律(比如和,差相同啊啥的,等差数列啊啥的)
打印的话分两种,一种是用二维数组(本题做法),一种是直接printf打印(A题做法)

#include<bits/stdc++.h>
using namespace std;

char mp[1000][1000];

int main()
{
    
    
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
    
    
		for(int j=1;j<=2*n-1;j++)
		{
    
    
			if(i==j||i+j==2*n)mp[i][j]='V';
			else mp[i][j]=' ';
		}
	}
	for(int i=1;i<=n;i++)
	{
    
    
		for(int j=1;j<=2*n-1;j++)
		{
    
    
			cout<<mp[i][j];
		}
		cout<<endl; 
	}
}

I
桶排序(可以用来完成去重,排序,统计元素个数)

#include<bits/stdc++.h>
using namespace std;

const int N=1e4+10;
int a[N],flag[N];//a用来桶排序,flag标记是否已经输出过了
int main()
{
    
    
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
    
    
		int x;
		cin>>x;
		a[x]++;
			
	} 
	for(int i=10000;i>=1;i--)
	{
    
    
		if(a[i]>0&&!flag[i])
		{
    
    
			flag[i]=1;
			cout<<i<<"-"<<a[i]<<endl; 
		}
	}
	return 0;
}

J
子区间求和,一维前缀和算法,注意对不正常p,q区间的调整。

#include<bits/stdc++.h>
using namespace std;

const int N=1e3+10;
long long a[N],s[N];
int main()
{
    
    
	int n,t,p,q;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
    
    
		cin>>a[i];
		s[i]=s[i-1]+a[i];
		//cout<<s[i]<<endl;
	}
	cin>>t;
	while(t--)
	{
    
    
		cin>>p>>q;
		int flag=1;
		if(q>n)
		{
    
    
			if(p>n)
			{
    
    
				cout<<0<<endl;
				flag=0;
			}
			q=n;
		}
		if(p<1)p=1;
		if(flag)cout<<s[q]-s[p-1]<<endl;
	}
	return 0;
}

K
找最大反向搜

#include<bits/stdc++.h>
using namespace std;

int main()
{
    
    
	int n,m,k;
	int flag=1;
	cin>>n>>m>>k;
	for(int i=k;i>=1;i--)
	{
    
    
		if(i%n==0&&i%m==0)
		{
    
    
			cout<<i;
			flag=0;
			break; 
		}
	}
	if(flag)cout<<-1;
	return 0;
}

L
高中排列组合(高考完记忆删除呜呜呜)含重复元素的排列,这个有公式的自己百度“重复元素的排列”

#include<bits/stdc++.h>
using namespace std;
int flag[30];
long long f(int n)
{
    
    
	long long q=1;
	for(int i=1;i<=n;i++)q*=i;
	return q;
}
int main()
{
    
    
	string s;
	int cnt=0,n=0;
	cin>>s;
	for(int i=0;s[i];i++)
	{
    
    
	//	if(flag[s[i]-'A']==0)cnt++;
		flag[s[i]-'A']++;
		++n;
	}
	long long res=f(n);
//	cout<<res<<endl; 
	for(int i=0;i<=25;i++)
	{
    
    
		if(flag[i]>0)
		{
    
    
			int t=f(flag[i]);
			res=res/t;
		}
	}
	cout<<res-1;
	return 0;
}

M
最大-最小+1即可
最大(n-1)max+min
最小(n-1)min+max

#include<bits/stdc++.h>
using namespace std;

int main()
{
    
    
	long long n,minn,maxn;
	cin>>n>>minn>>maxn;
	cout<<((n-1)*maxn+minn)-(maxn+(n-1)*minn)+1; 
	return 0;
}

N
约数个数为3可以推出这些数一定是质数的完全平方

除了1,一个数都有1和其本身两个约数,此时我们还需要一个约数
然后可能涉及如下一些结论(可能表述不是很好,建议百度一波)
1一般情况下约数总是成对出现的,如果要单次出现那么就是这一对约数相同。
2约数是奇数是完全平方数的充要条件
3唯一分解定理和约数个数定理

此时再经过一波观察规律(我承认是我数论知识太浅薄了,真让我说可能误人子弟)
唯 一 分 解 定 理 : N = p 1 c 1 p 2 c 2 p 3 c 3 p 4 c 4 p 5 c 5 … … 约 数 个 数 ( c 1 + 1 ) ( c 2 + 1 ) ( c 3 + 1 ) ( c 4 + 1 ) … … 唯一分解定理:N=p_1^{c_1}p_2^{c_2}p_3^{c_3}p_4^{c_4}p_5^{c_5}……\\ 约数个数(c_1+1)(c_2+1)(c_3+1)(c_4+1)……\\ N=p1c1p2c2p3c3p4c4p5c5(c1+1)(c2+1)(c3+1)(c4+1)
约数个数只能是(2+1)(0+1)(0+1)……
这种组合,那么就只有一个p^2这种可能,即质数的完全平方数

#include<bits/stdc++.h>
using namespace std;

typedef long long LL;
bool is_prime(LL x)//开long long!
{
    
    
    if (x < 2) return false;
    for (int i = 2; i <= x / i; i ++ )//不写i*i<=x或者i<=sqrt(x)
        if (x % i == 0)
            return false;
    return true;
}

int main()
{
    
    
    LL n,cnt=0;
    cin>>n;
    for(LL i=2;i<=n/i;i++)
    {
    
    
        if(is_prime(i))cnt++;
    }
    cout<<cnt;
}

O
这题很妙!
第i堆取i,标准重量(N+1)N/2,如果第r堆有问题,那么就会比标准多出r
即可直接知道第几堆。特判1即可

#include<bits/stdc++.h>
using namespace std;

int main()
{
    
    
	int n;
	cin>>n;
	if(n==1)cout<<0;
	else cout<<1;
	return 0;
}

P
因为p>0,所以避不开可能是奇数或者<6的
然后想想能不能二进制表示,然后看有几个1
我们要<=3个1,那么为何要小于呢,因为如果三个指数有相同的话就会合并啦,然后利用STL bitset实现即可

#include<bits/stdc++.h>
using namespace std;

int main()
{
    
    
	int n;
	cin>>n;
	bitset<100>b(n);
	if(n<6||n%2==1)puts("NO");
	else
	{
    
    
		if(b.count()<=3)puts("YES");
		else puts("NO");
	}
} 

Q
先输出一波1/n找规律,只有完全被2或者5整除的ok啦
三种:只能被2整除;只能被5整除;同时被2,5整除(即10)

#include<bits/stdc++.h>
using namespace std;

int n;
int main()
{
    
    
	int t;
	cin>>t;
	while(t--)
	{
    
    
		cin>>n;
		int tmp=n;
		if(tmp==1)puts("YES");
		else
		{
    
    
			while(1)
			{
    
    
				if(tmp%5==0&&tmp%2!=0)tmp/=5;
				else if(tmp%2==0&&tmp%5!=0)tmp/=2;
				else if(tmp%2==0&&tmp%5==0)tmp/=10;
				else
				{
    
    
					if(tmp==1)
					{
    
    
						puts("YES");
						break;
					}
					else
					{
    
    
						puts("NO");
						break;
					}
				}
			}	
		}
	}
	return 0;
}

剩下三题补不动了,大佬们有思路的话可以在评论区留言哟

反思:目前个人数论知识方面比较欠缺,博弈论,计算几何balabala
然后记得看清数据范围,开long long!。

然后这里放一个ph和我这蒟蒻聊到半夜的脑洞(坐等博客):将P题推广到底数为n,并由k个n^r组成,判断输入的数是否能被表示出来

猜你喜欢

转载自blog.csdn.net/qq_39354847/article/details/110293885