Codeforces每日一练 495B+55C+1280C

495B Modular Equations

传送门
题意:求有多少个x满足a mod x=b
如果满足题意,则有k*x=a-b,而且那就变成了分解因子,而且x必定大于b,从1到ab\sqrt{a-b}枚举即可,根号时间可以解决。

#include <bits/stdc++.h>
#define mod 1000000007
using namespace std;
#define ll long long
#define maxn 10005

int main() {
    ll a,b;
    cin>>a>>b;
    a-=b;
    if(a<0)cout<<0;
    else if(a==0)cout<<"infinity";
    else{
        ll ans=0;
        for (ll i = 1; i <=sqrt(a+b) ; ++i) {
            if(a%i==0){
                if(i>b)ans++;
                if(a/i!=i&&a/i>b)ans++;
            }
        }
        cout<<ans;
    }
    return 0;
}

55C Pie or die

传送门
题意:每次你可以把一个棋子移动一步,同时对手可以在边界上加上一块长为1的挡板,询问能否将某个棋子移到棋盘外。
画个图就可以看出来规律了,首先定义:
在这里插入图片描述
图中红点为当前棋子并向左移动,红线为挡板,此时挡板领先棋子1个单位,不难发现如果棋子移动方向上存在没有挡板的拐角,那么棋子就会追上一个单位,但是如果有两个挡板,就会落后一个,那么一种合理的挡板摆放就是在某条边两端各放两个,中间和棋子一条直线上放一个挡板,此时需要棋子到达四个方向边界所需步数都大于等于5
挡板如图:
在这里插入图片描述

#include <bits/stdc++.h>
#define mod 1000000007
using namespace std;
#define ll long long
#define maxn 105
struct node{
    int x,y;
}p[maxn];
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n,m,k;
    cin>>n>>m>>k;
    int fl=0;
    for (int i = 1; i <=k ; ++i) {
        cin>>p[i].x>>p[i].y;
        int r=m-p[i].y,d=n-p[i].x;
        if(r<=4||p[i].y-1<=4||d<=4||p[i].x-1<=4){
            fl=1;
        }
    }
    if(fl)cout<<"YES";
    else cout<<"NO";
    return 0;
}

1280C Jeremy Bearimy

传送门
牛客有一道弱化版的:
传送门
题意:一棵有2k个节点的边权树,分成k个点对,求出每个点对中两点距离之和的最大值和最小值。
先说说最大值,首先对于每棵子树,最理想的情况就是把其中的结点去和该子树外的结点相匹配,假设子树节点数为num[i],根节点的父节点为fa[i],那么想要尽量多的实现这种理想配对,那么i和fa[i]之间的边应该选择min(num[i],n-num[i])次,dfs处理子树就好了。
然后是最小值,考虑到最大值的写法,不难想出最小值就是尽量内部配对,但是如果节点数是奇数,就会多一个不能配对,这时候就应该选择根节点和父亲结点之间的边,即从子树外找一点参与匹配。

#include <bits/stdc++.h>
#define mod 1000000007
using namespace std;
#define ll long long
#define maxn 200005
map<pair<int,int>,ll>mp;
vector<int> g[maxn];
int num[maxn];
void calc(int x,int fa){
    num[x]=1;
    for(auto i:g[x]){
        if(i!=fa){
            calc(i,x);
            num[x]+=num[i];
        }
    }
}
int n;
ll ans=0,ans2=0;
void dfs(int x,int fa){
    if(mp[pair<int,int>(x,fa)]!=0){
        ans2+=mp[pair<int,int>(x,fa)]*min(num[x],2*n-num[x]);
    }
    else ans2+=mp[pair<int,int>(fa,x)]*min(num[x],2*n-num[x]);
    if(num[x]%2==1){
        if(mp[pair<int,int>(x,fa)]!=0)ans+=mp[pair<int,int>(x,fa)];
        else ans+=mp[pair<int,int>(fa,x)];
    }
    for(auto i:g[x]){
        if(i!=fa){
            dfs(i,x);
        }
    }
}
int main() {
    int t;
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin>>t;
    while(t--){
        ans2=0;
        ans=0;
        memset(num,0, sizeof(num));
        mp.clear();

        cin>>n;
        for (int j = 1; j <=2*n ; ++j) {
            g[j].clear();
        }
        for (int i = 1; i <2*n ; ++i) {
            int u,v;
            ll w;
            cin>>u>>v>>w;
            mp[pair<int,int>(u,v)]=w;
            g[u].push_back(v);
            g[v].push_back(u);
        }

        calc(1,0);
        dfs(1,0);
        cout<<ans<<" "<<ans2<<endl;
    }
    return 0;
}

(大晚上写的,可能有点乱

posted @ 2020-04-03 17:42  Bazoka13  阅读(112)  评论(0编辑  收藏  举报