2018广东工业大学新生赛(复赛1)

Problem A: 哦吼?GJC要防AK了?
思路:如果Y不是X的因数,因为X是自身的倍数,所以X是X的倍数而不是Y的倍数,反之,由于Y是X的因数,所以X的任何倍数都是Y的倍数;故该题只需判断X%Y;

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
	long long x,y;cin >> x >> y;
	if(x%y)
		cout << x;
	else
		cout << "-1";
	return 0;
}

Problem B: 730的天花板
思路:dp,设n时方案数为dp[n],则当n+1时,若第一列只有11方块,则方案数为dp[n-1],若第一第二行有22方块,则方案数为2dp[n-1],即得
**dp[n+1] = dp[n]+2dp[n-1]
**;

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll mod = 19260817;
ll dp[10000005];
int main()
{
	dp[0] = dp[1] = 1;dp[2] = 3;
	for(int i = 3;i <= 10000000;++i)
		dp[i] = (dp[i-1]+2*dp[i-2])%mod;
	int T;cin >> T;
	while(T--)
	{
		int n;cin >> n;
		cout << dp[n] << endl;
	}
	return 0;
 } 

Problem C: gugugu
思路:模拟;

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
int a[100005];
int main()
{
	a[1] = 1;
	for(int i = 2;i <= sqrt(100005);++i)
	{
		if(!a[i])
			for(int j = 2;i*j < 100005;++j)
				a[i*j] = 1;
	}
	int n,sum = 0;cin >> n;
	while(n--)
	{
		char s[105];cin >> s;
		int len = strlen(s);
		for(int i = 0;i < len-1;++i)
			if(s[i]=='G'||s[i]=='g')
				if(s[i+1]=='u'||s[i+1]=='U')
					++sum;
	}
	if(a[sum])
		cout << "gu";
	else
		cout << "gugugu";
	return 0;
}

Problem D: 不可思议唤来不可思议β
思路:排列组合题,假设有333457789这九个数,假设每个数字不同则有A(9,9)种排列,因为3与7存在重复运算=>A(3,3),A(2,2),则真正的排列数为A(9,9)/A(3,3)/A(2,2);在此基础上,拿出其中数字3,则余下数字的排列数就是3在某一位的出现次数,该排列数为A(8,8)/A(2,2)/A(2,2),以此类推,求出一个位上所有数字的重复次数与其乘积之和,即可算得答案;

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
ll A[15];
int main()
{
	A[0] = A[1] = 1;
	for(int i = 2; i <= 10;++i)
		A[i] = A[i-1]*i;
	int n;
	while(scanf("%d",&n)&&n)
	{
		ll a[15] = {0};
		for(int i = 0;i < n;++i)
		{
			int tt;
			cin >> tt;
			a[tt]++;
		}
		ll sum = 0;
		for(int i = 1;i <= 9;++i)
		{
			if(!a[i])
				continue;
			ll pos = i*A[n-1];
			for(int j = 0;j < 10;++j)
			{
				if(a[j])
				{
					if(j == i)
						pos /= A[a[j]-1];
					else
						pos /= A[a[j]];
				}
			}
			sum += pos;
		}
		ll ans = 0;
		for(int i = 1;i <= n;++i)
			ans = ans*10+sum;
		printf("%lld\n",ans);
	}
	return 0;
}

Problem E: Hacking to the Gate
思路:看不懂数学符号,看样例盲猜等于1,发现wa了又盲猜n,对了

Problem F: 维生素
思路:一开始我是用位运算+dp的,后来发现算法有问题,在某大佬指导下用了贪心算法,具体贪心方法如下;

abc可以由abc,a+bc,ab+c,ac+b,a+b+c,三种方法得到,先记录含a的饮料,再记录含b的饮料,因此类推,设v[a]为含a饮料价格的最小值,则答案为v[abc],v[a]+v[bc],v[b]+v[ac],v[c]+v[ab],v[a]+v[b]+v[c]中的最小值;

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const ll maxn = 1e8;
int a[10];
int main()
{
	int T;cin >> T;
	while(T--)
	{
		int n;cin >> n;
		for(int i = 0;i < 8;++i)
			a[i] = maxn;
		for(int i = 0;i < n;++i)
		{
			char t[8];int p;
			cin >> p;scanf("%[^\n]",t);
			int len = strlen(t),tt = 0;
			for(int j = 0;j < len;++j)
			{
				if(t[j] == 'A')//用位代替维生素;
					tt += 4;
				else if(t[j] == 'B')
					tt += 2;
				else if(t[j] == 'C')
					tt += 1;
			}
			if(tt==1&&p < a[1])
				a[1] = p;
			else if(tt==2&&p<a[2])
				a[2] = p;
			else if(tt==3)
			{
				if(p < a[1])
					a[1] = p;
				if(p < a[2])
					a[2] = p;
				if(p < a[3])
					a[3] = p;
			}
			else if(tt==4&&p<a[4])
				a[4] = p;
			else if(tt==5)
			{
				if(p < a[4])
					a[4] = p;
				if(p < a[1])
					a[1] = p;
				if(p < a[5])
					a[5] = p; 
			}
			else if(tt==6)
			{
				if(p < a[4])
					a[4] = p;
				if(p < a[2])
					a[2] = p;
				if(p < a[6])
					a[6] = p;
			}
			else if(tt==7)
			{
				if(p < a[1])
					a[1] = p;
				if(p < a[2])
					a[2] = p;
				if(p < a[3])
					a[3] = p;
				if(p < a[4])
					a[4] = p;
				if(p < a[5])
					a[5] = p;
				if(p < a[6])
					a[6] = p;
				if(p < a[7])
					a[7] = p;
			}
		}
		int ans = min(a[1]+a[2]+a[4],a[6]+a[1]);
		ans = min(ans,a[5]+a[2]);
		ans = min(ans,a[4]+a[3]);
		ans = min(ans,a[7]);
		if(ans < maxn)
		cout << ans << endl;
		else
		cout << "-1" << endl;
	}
	return 0;
 } 

Problem G: 你选择的这个世界
思路:首先,如果硬币最终为正面,则其被翻奇数次,一个硬币被翻的次数等于其因数的个数,则要求正面的硬币因数个数为奇数,现拿4举例,4的因数有1,2,4,而6的因数为1,2,3,6,易发现当编号为平方数时因数个数为奇数个,因为若m = a*b,则a,b分别为m的因数或ab,两者为m的同一个因数,若ab则m为平方数,若m不为平方数,则易知因数成对存在,有偶数个;

#include<cmath>
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
int main()
{
	int T;cin >> T;
	while(T--)
	{
		ll n;cin >> n;
		for(ll i = 1;i <= sqrt(n);++i)
		{
			if(i+1 <= sqrt(n))
				cout << i*i << ' ';
			else 
				cout << i*i;
		}
		cout << endl;
	}
	return 0;
}

Problem H: 邱总的游戏
思路:其实这道题我是看题解的,博弈的必胜态实在找不到
题解链接;

Problem I: 二律的日常
思路:这题还是用贪心,首先是按顺序看的,前面的能买就买,而当价格为0时就是必买,设价格为0的物品有m件,则当m > k时不可能只买k件,当 n == k时可以带无限多的钱,排除这两种情况,从余下价格不为0的物品中按顺序选m-k件4并加上挑选后余下物品最低价减1的钱数即为最多带的钱;

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
ll a[100005]; 
int main()
{
	int T;cin >> T;
	while(T--)
	{
		int n,k;cin >> n >> k;
		for(int i = 0;i < n;++i)
			scanf("%lld",a+i);
		int ans;
		if(k == n)
			ans = -2;
		else
		{
			int tail = 0;
			while(tail < k)
				ans += a[tail++];
			sort(a+k,a+n);
			int i ;
			for(i = k;i < n&&tail;++i)
				if(a[i] == 0)
					ans -= a[--tail];
			if(!tail&&!a[i])
				ans = -1;
			else 
			{
				sort(a+tail,a+n);
				ans += a[tail]-1;
			}
		}
		if(ans == -1)
			cout << "alsnb" << endl;
		if(ans == -2)
			cout << "ksfnb" << endl;
		if(ans >= 0)
			cout << ans << endl;
	}
	return 0;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值