湖南大学程序设计竞赛新生赛(重现赛)

入口

A The GCD of Fibonacci Numbers

题意: 求gcd(fn,fm)
题解: 主要是题意提示的比较明显,题意gcd(fn,fm)<=45,所以先求出前45项的斐波那契数列然后输出f[gcd(n,m)]

#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std ;
const int N = 50 ;
int f[N] ; 
int main(){
    f[0] = 0 , f[1] = 1 ;
    for (int i=2 ; i <= 45; ++i)
        f[i]=f[i-1]+f[i-2] ;
    int t ; scanf("%d",&t);
    while(t--){
        int n , m ;
        scanf("%d%d",&n,&m) ;
        printf ("%d\n",f[__gcd(m,n)]) ;
    }
    return 0 ;
}
B Xu1024’s treasure chest

题意: 给出A求 符合B^2 - A^2 = C^2 - B^2.的B和C
题解: 看了别人的题解就是说带入A=1可以得出B=5,C=7所以B=5A,C=7A,。。。。。。。。。。(os:还有这种解法。。。。。)

#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std ;
typedef long long ll;
const int mod = 1e9 ;
int main(){
    ll a ; scanf("%lld",&a) ;
    if(a==0)    printf("-1\n") ;
    else    printf("%lld %lld\n",5*abs(a),7*abs(a)) ;
    return 0 ;
}
C Binbin’s treasure map

题意: 迷宫中#是不能走的,.是能走的,$是可以获得一个金币的,走的时候可以任意选择一个点开始,中间有一个机会可以换到任意一个点,问最多能获得多少金币。
题解: 搜索两个联通块就行然后选择两个最多金币的联通块输出,但是有个要注意的点就是,边界外的一圈是可以走的,所以输入的时候边界是1~n然后判断出界的时候是要0 ~n+1才能过

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std ;
const int N = 505 ; 
bool vis[N][N] ; 
char g[N][N] ; 
int n , m , cnt ; 
int ans[N*N] ; 
int dir[4][2] = {{-1,0},{0,-1},{1,0},{0,1}} ; 
bool cmp(int a , int b){
	return a > b ; 
}
void dfs(int dx , int dy){
	if(g[dx][dy] == '$')	++ cnt ; 
	vis[dx][dy] = true ; 
	for(int i = 0 ; i < 4 ; ++ i){
		int x = dx + dir[i][0] ; 
		int y = dy + dir[i][1] ; 
		//边界从0~n+1
		if(x>=0&&x<=n+1&&y>=0&&y<=m+1&&!vis[x][y]&&g[x][y]!='#')
			dfs(x,y) ; 
	}
	return ; 
}
int main(){
	cin >> n >> m ; 
	for(int i = 1 ; i <= n ; ++ i)
		for(int j = 1 ; j <= m ; ++ j)
			cin >> g[i][j] ;
	int k = 0 ; 
	for (int i = 1 ; i <= n ; ++ i){
		for(int j = 1 ; j <= m ; ++ j){
			if(vis[i][j] && g[i][j] == '$'){
				cnt = 0 , dfs(i,j) ; 
				ans[k++] = cnt ; 
			}
		}
	}
	sort(ans,ans+k,cmp) ; 
	cout << ans[0]+ans[1] << endl ;
	return 0 ; 
}
D Day Passing

题意: 给出周几和n,m问nm天后是周几
题解: 其实就是一个快速幂取模,但是n的范围为1e100000要先处理一下,在输入的时候(字符串转为数时一遍转一遍取模%7)

#include <cstdio>
#include <iostream>
#include <map>
using namespace std ; 
typedef long long ll ;
string s[7] = {"Mon","Tue","Wed","Thu","Fri","Sat","Sun"} ;
ll fast(ll a , ll b , ll p){
    a %= p ;
    ll res = 1 ; 
    while(b){
        if(b&1) res = res*a%p ;
        a = a*a%p ;
        b >>= 1 ;
    }
    return res ;
}
int main(){
    string day , x ; ll n , m ;
    cin >> day >> x >> m ;
    for (int i = 0 ; i <x.length() ; ++ i)
        n = (n*10+(x[i]-'0'))%7 ;//输入处理
    int i = 0 ;
    for( ;i<7;++i)
        if(s[i]==day)   break ;
    ll pos = fast(n,m,7) ;//快速幂取模
    cout << s[(i+pos)%7] << endl ;
    return 0 ;
}
F Kuangyeye’s Game

题意:给出若干点的坐标问是否全部在同一条直线上
题解:每两点之间斜率相同即可。

#include <cstdio>
#include <cmath>
const int eps=1e-6 ; 
const int N = 1005 ; 
int a[N][2] , n ;
int main(){
	scanf("%d",&n) ;
	for(int i = 0 ; i < n ; ++ i)
		scanf("%d%d",&a[i][0],&a[i][1]) ; 
    if(n <= 2)   {
        printf ("Yes\n") ;
        return 0 ; 
    }
    int x = a[1][0]-a[0][0] , y = a[1][1]-a[0][1] ; 
    bool flag = true ; 
    for(int i = 2 ; i < n ; ++ i){
        if(y*(a[i][0]-a[0][0]) != x*(a[i][1]-a[0][1])){
            flag = false ; 
            break ; 
        }
    }
    if(flag)    printf ("Yes\n") ;
    else    printf("No\n") ;
	return 0 ; 
} 
G Buy Keys

题意: 10块钱可以买三把钥匙,3块钱可以买1把钥匙,给出金额问能买最少的钥匙数并且不剩下钱。
题意: 从n/10到0从大到小一个个试能否与3组合如果可以就计算输出,不行就输出orz

#include <cstdio>
int cal(int n){
    int a=n/10 ;
    for(int i=a;i>=0;--i){//从大到小保证最后的钥匙数最少
        if((n-i*10)%3==0)//匹配成功返回i值
            return i ;
    }
    return -1 ;//10和3不能组合
}
int main(){
    int n ;
    scanf("%d",&n) ; 
    if(cal(n)==-1)  printf("orz\n");
    else    printf("%d\n",3*cal(n)+(n-10*cal(n))/3) ;
    return 0 ;
}
H Dice

题意: 玩游戏最多玩n轮,只要有一轮赢了就不再继续玩,问赢的概率
题解: 直接模拟,前一轮的当前计算赢的概率乘于当前轮赢的概率(0.5)

#include <cstdio>
int main(){
    int t ; scanf("%d",&t);
    while(t--){
        int n ; scanf("%d",&n) ;
        double ans = 0 , temp = 0 ;
        for(int i=1;i<=n;++i){
            ans += 0.5*(1-temp) ; temp = ans ; 
        }
        printf ("%.4lf\n",ans) ;
    }
}
J Fake Nim

题意:A和B两人轮流取石子,有n堆石头,A只取一堆石头的偶数个,B只取奇数个,当少于两个石头时A不会取,谁拿走最后一块石头谁就赢。
题解:还是看看大佬的题解吧。。。。。(至今不会博弈。。。。。)
在这里插入图片描述

#include <cstdio>
typedef long long ll ;
int main(){
	int n ; ll x ; 
	scanf("%d",&n) ;
	int odd = 0 ;
	for(int i = 0 ; i < n ; ++ i)
		scanf("%d",&x) , odd += x&1 ; 
	if(n==1 && odd==0)    printf("DaDa\n") ;
    else    printf("TuTu\n") ; 
	return 0 ; 
} 
L Special number

题意: 一个数能被少于三个数整除的数为特别数,给出一个区间[L,R]问里面的特别数有几个。
题解: 其实就是在问素数有几个,但是要注意的是范围包括0,而0不是素数。

#include <cstdio>
bool isprime(int n){
    if(n==0)    return false ;
	if(n <= 3)	return true ;
	for (int i=2 ; i*i <= n+1 ; ++ i)
		if(n%i == 0)	return false ;
	return true ; 
}
int main(){
	int l , r , cnt = 0 ; 
	scanf("%d%d",&l,&r) ; 
	for(int i=l ; i<=r ; ++i){
		if(isprime(i))	++cnt ;
	}
	printf("%d\n",cnt);
	return 0 ;
}
M XOR Sum

题意:给出区间[L,R]问该区间异或和为多少。
题解:l和r的数据范围到1e18肯定不能直接遍历,遍历100打表发现没四个数异或为0,所以中间每四个就不用去算了,算头尾不是四的倍数的就行。

#include <cstdio>
#include <iostream>
using namespace std ; 
typedef long long ll ; 
int main(){
	ll l,r , ans = 0 ;
	cin >> l >> r ; 
	if(r-l > 4){
		ll flag = l ; 
		for(ll i = l ; i <= r ; ++ i){
			if(i%4 != 0)	ans ^= i ; 
			else	break ; 
		}
		for(ll i = r ; i >= l ; -- i){
			if((i+1)%4!=0)	ans ^= i ; 
			else	break ; 
		}
	}
	else
		for(ll i = l ; i <= r ; ++i)	ans ^= i ; 
	cout << ans << endl ; 
	return 0 ; 
} 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值