Codeforces Round #685 (Div. 2)

A. Subtract or Divide

题意就是
给一个数n,通过两种操作把他变成 1, 问最少操作的次数
操作一,n 除以 除自己以外的因子
操作二,n 减一

上来以为和素数有关系,想的是
n - > (n的最小质因子)|| (n - 1)

然后交了两发wa,发现和质数没关系

1
2 -> 1
3 -> 2 -> 1
剩下的偶数 -> 2 -> 1
剩下的奇数 -> 该奇数减一(偶数) -> 2 -> 1

就这几种情况,就没了,还是得从题目本身去开始想,自己过于信任自己的素数筛了,多测几组样例很快就应该能知道答案

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define fi first
#define se second
#define endl '\n'
#define debug(x) cout << #x << " = " << x << "\n"
 
const int N = 200010;
 
bool st[N];
int primes[N];
int cnt;
 
int sushu(int n){
    for(int i = 2;i <= n;i ++){
        if(st[i] == 0)
            primes[cnt ++] = i;
        for(int j = 0; primes[j] <= n / i; j ++){
            st[primes[j] * i] = true;
            if(i % primes[j] == 0) break;
        }
    }
}
 
int main(){
    //sushu(N-1);
    int _;
    cin >> _;
    while(_--){
        int a;
        cin >> a;
 
        if(a == 1)
            cout << 0 << endl;
        else if(a == 2) cout << 1 << endl;
        else if(a == 3) cout << 2 << endl;
        else if(a % 2 == 0) cout << 2 << endl;
        else cout << 3 << endl;
    }
    return 0;
}

C. String Equality

题意给你两个字符串,让你对第一个字符串进行操作,把第一个变成第二个字符串,看可不可能

操作一 交换两个相邻的字符
操作二 把连续的k个相同的字符++, 即a -> b,b -> c 如果到达"z"的话就不在++

首先相邻的两个字符可以进行交换,那么说明和顺序无关,(冒泡排序原理)

那么就和每个字符的个数有关系了,按照题目要求进行个数的交换,如果第一个字符串内各个字母的个数和第二个字符串内各个字母的个数相等即为可以

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define fi first
#define se second
#define endl '\n'
#define debug(x) cout << #x << " = " << x << "\n"
 
const int N = 1000100;
 
int n, k;
char ch1[N];
char ch2[N];
int z1[N], z2[N];
 
bool cmp(const int &a, const int &b){
    return a < b;
}
 
int main(){
    int _;
    cin >> _;
    while(_--){
 
        for(int i = 1;i <= 26;i ++) 
            z1[i] = 0, z2[i] = 0;
 
        cin >> n >> k;
        cin >> ch1 >> ch2;
        for(int i = 0;i < n;i ++){
            z1[ch1[i] - 'a' + 1]  ++;
            z2[ch2[i] - 'a' + 1]  ++;
        }
 
        for(int i = 1;i <= 25;i ++)
            if(z1[i] > z2[i]){
                while(z1[i] > z2[i] && i <= 25){
                    z1[i] -= k;
                    z1[i + 1] += k;
                }
            }
 
        int ans = 0;
 
        for(int i = 1;i <= 26;i ++)
            if(z1[i] != z2[i]) 
                ans = 1;
 
        if(ans == 0) cout << "Yes" << endl;
        else cout << "No" << endl;
 
    }   
    return 0;
}

D. Circle Game

题意,两个人玩游戏,从(0,0)开始,每个人可以选择 x坐标+k 或者 y坐标+k ,在以(0,0)为圆心半径为 n 的圆内上述的操作才是合法的,如果该人操作完后另一个人无法操作,那么该人赢

一道博弈,
一个人怎么调节另一个人的活动呢
如果这个人选择x+k,那么另一个人就选择y+k,这样就一直在斜率为1的直线上了
那么找先手必胜态,先手选完后无论后手怎么选,先手都能把当前状态调整到斜率为1的直线上,那么就是(i * k + k,i * k)在圆内
那么后手必胜态呢,无论先手怎么选,后手把先手调整到斜率为1的直线上,那么就是(i * k,i * k)在圆内

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值