湖南大学程序设计竞赛新生赛

题目链接:https://ac.nowcoder.com/acm/contest/3674
题解链接:https://ac.nowcoder.com/discuss/361704?type=101&order=time&pos=&page=1

A - The GCD of Fibonacci Numbers

对于两个斐波那契数的最大公因数,有一个公式: g c d ( f m , f n ) = f g c d ( m . n ) gcd(f_m,f_n)=f_{gcd(m.n)} gcd(fm,fn)=fgcd(m.n)

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

int gcd(int a, int b)
{
	if (b == 0) return a;
	return gcd(b, a % b);
}

int f[50] = {0, 1, 1};

int main(void)
{
	for (int i = 3; i <= 45; i++)
		f[i] = f[i - 1] + f[i - 2];
	int t, m, n;
	scanf("%d", &t);
	while (t--){
		scanf("%d%d", &m, &n);
		int gc = gcd(m, n);
		printf("%d\n", f[gc]);
	}
	return 0;
}

E - Days passing

这道题n可能会很大,需要用string来存储,再按位进行处理

#include <cstdio>
#include <string>
#include <iostream>
using namespace std;

typedef long long ll;
string weekday[10] = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};

ll mod_pow(ll x, ll n, ll mod)
{
	ll res = 1; 
	while (n > 0){
		if (n & 1) res = res * x % mod;
		x = x * x % mod;
		n >>= 1;
	}
	return res;
}

int main(void)
{
	ll idx;
	string today;
	cin >> today;
	for (int i = 0; i < 7; i++){
		if (weekday[i] == today){
			idx = i;
		}
	}
	string s;
	ll n = 0, m;
	cin >> s >> m;
	for (int i = 0; i < s.size(); i++){
		n *= 10;
		n += s[i] - '0';
		n %= 7;
	}
	ll num = mod_pow(n, m, 7);
	idx = (idx + num) % 7;
	cout << weekday[idx] << endl;
	return 0;
}

F - Kuangyeye’s Game

一位大佬的天秀代码

#include <iostream>
using namespace std;

int main(void)
{
    int n, x1, y1, x2, y2, a, b;
    cin >> n >> x1 >> y1;
    if (n >= 2) 
		cin >> x2 >> y2;
    for (int i = 3; i <= n; i++){
        cin >> a >> b;
        if ((a - x1) * (y2 - y1) != (b - y1) * (x2 - x1)){
			cout << "No" << endl;
			break;
		}
    }
    cout << "Yes" << endl;
    return 0;
}

G - Buying Keys

如果能够花完手上的钱,输出最少能购买的钥匙数,如果不能花完手上的钱,输出"orz"
买钥匙有两种方法:三元一把,十元三把,所以我们要尽可能多的以10元的方式购买钥匙才能买到更少的钥匙。
先一把一把的买,可能有两种情况:
1)最后手上的钱是10的整倍数(包括0),此时以10元的方式花完所有钱。
2)最后手上的钱小于3元,这样说明花不完手上的钱。

#include <cstdio>

int main(void)
{
	int n, ans = 0;
	scanf("%d", &n);
	while (true){
		if (n % 10 == 0){
			ans += (n / 10) * 3;
			printf("%d\n", ans);
			break;
		}
		if (n < 3){
			printf("orz\n");
			break;
		}
		n -= 3;
		ans += 1;
	}
	return 0;
} 

H - Dice

第一轮使用1元,第二轮使用2元,第三轮使用4元,依次类推。
最多玩n局,只要n局中有一局胜利,就会赢钱,且不会进行下面的游戏。n局全输的话才会亏损。
求赢钱的概率

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

int main(void)
{
	int t, n;
	double ans, p;
	scanf("%d", &t);
	while (t--){
		scanf("%d", &n);
		ans = 0;
		p = 0.5;
		for (int i = 0; i < n; i++){
			ans += p;
			p /= 2;
		}
		printf("%.4lf\n", ans);
	}
	return 0;
}

J - Fake Nim

题目:DaDa先手,并且只能拿偶数个,TuTu后手,只能拿奇数个,当剩下的每一堆都为1时,此时DaDa无法拿,这时对于DaDa来说就是必败局势。

1、因为DaDa拿的是偶数个,所以不能改变局势,比如一堆如果是偶数个,DaDa拿了之后仍然是偶数个,如果是奇数个,DaDa拿了之后仍然是奇数个。
2、因为TuTu拿的是奇数个,所以TuTu能够改变局势。
3、只要DaDa面对的局势中有一堆是奇数个,DaDa就无法获胜,最后只能由TuTu来拿完。
4、当仅存在一堆并且个数是偶数个时,DaDa才能获胜。
5、当仅存在一堆并且个数是奇数个时,TuTu可以直接拿完。当存在多堆时,TuTu总能让个数出现奇数个。此时TuTu获胜。

#include <cstdio>

int main(void)
{
	int n, t;
	scanf("%d%d", &n, &t);
	if (n == 1 && t % 2 == 0)
		printf("DaDa\n");
	else
		printf("TuTu\n");
	return 0;
}

L - Special number

求给出的区间中有多少个数能被少于三个数整除。
比如1 只能被自己整除,满足条件。2只能被1和2整除,满足条件

#include <cstdio>
#include <cmath>
using namespace std;

bool judge(int n)
{
	if (n == 0)//0能被无数正数整除
		return false;
	else if (n == 1)
		return true;
	for (int i = 2; i <= sqrt(n); i++){
		if (n % i == 0){
			return false;
		}
	}
	return true;
}

int main(void)
{
	int l, r;
	scanf("%d%d", &l, &r);
	int ans = 0;
	for (int i = l; i <= r; i++){
		if (judge(i))
			ans++;
	}
	printf("%d\n", ans);
	return 0;
}

M - XOR sum

一位大佬的代码,利用公式求出前缀和

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

ll f(ll x)
{
    if (x % 4 == 1) return 1;
    else if (x % 4 == 2) return x + 1;
    else if (x % 4 == 3) return 0;
    else return x; 
}

int main(void)
{
    ll l, r;
    cin >> l >> r;
    cout << (f(l - 1) ^ f(r)) << endl;
    return 0;
}
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值