Codeforces Round 901 (Div. 2)

发布时间 2023-10-19 17:40:56作者: du463

Codeforces Round 901 (Div. 2)

比赛链接
"考古"啦!之前没有做,现在补上

A. Jellyfish and Undertale

题目链接

思路:

按理说用模拟应该也是可以做到的,但是我应该没有写好,因为我们要找的是最大时间,所以我们每次加上的是min(a-1,x[i]),这样就可以保证是最大时间,最后注意一下数据大小就可以了

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=110;
ll x[N];
void solve(){
    ll a,b,n;
    cin>>a>>b>>n;
    for(int i=1;i<=n;i++){
        cin>>x[i];

    }   
    ll ans=b;
    for(int i=1;i<=n;i++){
        ans+=min(a-1,x[i]);
    }
    cout<<ans<<endl;
    
}
int main(){
    int t;
    cin>>t;
    while(t--){
        solve();
    }
    return 0;
}

B. Jellyfish and Game

题目链接

思路:

经典的博弈论的问题,我们只需要看看最后一次是谁执行的就可以了。

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=55;
ll a[N],b[N];

void solve(){
	int n, m, k;
        cin >> n >> m >> k;
        ll ans = 0;
 
        for (int i = 1; i <= n; i++) {
            cin >> a[i];            
        }
        for (int i = 1; i <= m; i++) {
            cin >> b[i];
            
        }
        sort(a + 1, a + n + 1);
        sort(b + 1, b + m + 1);
 
        if (a[1] < b[m]) {
            swap(a[1], b[m]);
            sort(a + 1, a + n + 1);
            sort(b + 1, b + m + 1);
        }
        
        if (k % 2 == 0) {
            swap(a[n], b[1]);
        }
        for (int i = 1; i <= n; i++) {
            ans += a[i];
        }
        cout << ans << endl;
}
int main(){
	int t=1;
	cin>>t;
	while(t--){
		solve();
	}
	return 0;
}

C. Jellyfish and Green Apple

题目链接

思路:

参考
第一步,使n=n%m,也就是先一人拿n/m个果,然后剩下的n就严格小于m。

第二步,剩下n个果子平均分给m个人,给n切为大小相同的片,至少lcm(n,m)(最小公倍数)片才能均分。lcm(n,m)=n*m/gcd(n,m),也就是平均每人n/gcd(n,m)片,也就是每个果子分成m/gcd(n,m)片,因为果子只能对半分,m/gcd(n,m)必须是2的整数次幂。

第三步,每人n/gcd(n,m)片,我们可以先玩个1024,把最小的两片合成中片,两个中片合成大片。。。。。其实就是二进制表示的n/gcd(n,m)中1的个数,假设这个数字是x,每切一刀果子片数+1,那么一共要xm片,初始有n个,答案就是xm-n

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b){
    return b?gcd(b,a%b):a;
    
}//求的是两个数的最大公约数
ll lcm(ll a,ll b){
    return a*b/gcd(a,b);//与最大公约数相结合,可以快速求出最小公倍数
}
void solve(){
	ll n,m;
	cin>>n>>m;
	n%=m;
	if(!n){
		cout<<0<<endl;
		return ;

	}
	
	ll x=lcm(n,m);
	ll a=x/n;
	ll b=x/m;
	ll c=a&-a;
	if(c!=a){
		cout<<-1<<endl;
		return ;
		
	}
	int ans=0;
	while(b){
		b=b-(b&-b);
		ans++;
	}
	cout<<1ll*ans*m-n<<endl;

}
int main(){
	int t;
	cin>>t;
	while(t--){
		solve();
	}
	return 0;

}