Codeforces Round #346 (Div. 2)

A:在一个环上的某点正向或反向走,问最后在哪个位置。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
#include<vector>
#include<queue>
#include<cmath>
#include<stack>
#include<set>
#include<map>
#define INF 0x3f3f3f3f
#define Mn 1010
#define Mm 2010
#define mod 1000000007
#define CLR(a,b) memset((a),(b),sizeof((a)))
#define CPY(a,b) memcpy ((a), (b), sizeof((a)))
#pragma comment(linker, "/STACK:102400000,102400000")
#define ul u<<1
#define ur (u<<1)|1
using namespace std;
typedef long long ll;
int main() {
    int a,n,b;
    scanf("%d%d%d",&n,&a,&b);
    while(b<0) {
        b=n+b;
    }
    int k=(a+b)%n;
    if(k==0) cout<<n<<endl;
    else cout<<k<<endl;
    return 0;
}

B:在一些赛区中选出前两名分数最高的,如果结果不唯一输出“?”;

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
#include<vector>
#include<queue>
#include<cmath>
#include<stack>
#include<set>
#include<map>
#define INF 0x3f3f3f3f
#define Mn 10005
#define Mm 2000005
#define mod 1000000007
#define CLR(a,b) memset((a),(b),sizeof((a)))
#define CPY(a,b) memcpy ((a), (b), sizeof((a)))
#pragma comment(linker, "/STACK:102400000,102400000")
#define ul u<<1
#define ur (u<<1)|1
using namespace std;
typedef long long ll;
struct node {
    int val;
    string s;
    node (){}
    node(int val,string &s) :val(val),s(s){}
    bool operator < (node const a) const {
        return val>a.val;
    }
};
vector<node> v[Mn];
int main() {
    int n,m;
    string s;
    int k,p;
    cin>>n>>m;
    for(int i=1;i<=n;i++) {
        cin>>s>>k>>p;
        v[k].push_back(node(p,s));
    }
    for(int i=1;i<=m;i++) sort(v[i].begin(),v[i].end());
    for(int i=1;i<=m;i++) {
        if(v[i].size()>=3) {
            if(v[i][2].val==v[i][1].val) cout<<"?"<<endl;
            else cout<<v[i][0].s<<" "<<v[i][1].s<<endl;
        }else {
            cout<<v[i][0].s<<" "<<v[i][1].s<<endl;
        }
    }
    return 0;
}


C:有很多玩具,第i个玩具的价格是i,现在已经买了一些玩具,给你m元,问你最多还可以买多少玩具。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
#include<vector>
#include<queue>
#include<cmath>
#include<stack>
#include<set>
#include<map>
#define INF 0x3f3f3f3f
#define Mn 100010
#define Mm 2000005
#define mod 1000000007
#define CLR(a,b) memset((a),(b),sizeof((a)))
#define CPY(a,b) memcpy ((a), (b), sizeof((a)))
#pragma comment(linker, "/STACK:102400000,102400000")
#define ul u<<1
#define ur (u<<1)|1
using namespace std;
typedef long long ll;
int a[Mn],b[Mn];
map<int,int> mp;
int main() {
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++) {
        scanf("%d",&a[i]);
        mp[a[i]]=1;
    }
    int cnt=0;
    for(int i=1;;i++) {
        if(mp[i]) continue;
        if(i<=m) {
            b[cnt++]=i;
            m-=i;
        } else break;
    }
    cout<<cnt<<endl;
    for(int i=0;i<cnt;i++) {
        printf("%d ",b[i]);
    }
    return 0;
}

D:从一个点绕湖走,计算危险的点有多少个,定义为:有掉进湖的趋势的点。

题目保证从西南角出发,湖一定在右边,所以我们只要判断有多少个拐弯点就行了。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
#include<vector>
#include<queue>
#include<cmath>
#include<stack>
#include<set>
#include<map>
#define INF 0x3f3f3f3f
#define Mn 200010
#define Mm 2000005
#define mod 1000000007
#define CLR(a,b) memset((a),(b),sizeof((a)))
#define CPY(a,b) memcpy ((a), (b), sizeof((a)))
#pragma comment(linker, "/STACK:102400000,102400000")
#define ul u<<1
#define ur (u<<1)|1
using namespace std;
typedef long long ll;
int x[Mn],y[Mn];
int main() {
    int n;
    cin>>n;
    for(int i=1;i<=n+1;i++)
        scanf("%d%d",&x[i],&y[i]);
    int ans=0;
    for(int i=3;i<=n+1;i++) {
        if(y[i-2]==y[i-1]&&x[i-1]>x[i-2]) {
            if(y[i]>y[i-1]) ans++;
        }
        else if(y[i]==y[i-1]&&x[i]>x[i-1]) {
            if(y[i-2]>y[i-1]) ans++;
        } else if(y[i-2]==y[i-1]&&x[i-1]<x[i-2]){
            if(y[i]<y[i-1]) ans++;
        } if(y[i]==y[i-1]&&x[i]<x[i-1]) {
            if(y[i-2]<y[i-1]) ans++;
        }
    }
    cout<<ans<<endl;
    return  0;
}

E:给你n个点,m条无向边,没有自环,重边,现在要你将这些点定向,让最后入度为0的点最少,输出最少有多少个入度不为0的点。

可以知道如果一个连通图有环,那么这个连通图的点入度都可以为0,如果没有环,那么就可以构成树,只有根这一个。

直接用dfs或并查集判环。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<vector>
#include<queue>
#include<set>
#include<stack>
#include<map>
#include<algorithm>
#include<cmath>
#define INF 0xfffffff
#define MAX 100005
#define mod 10000007
#define CLR(a,b) memset((a),(b),sizeof((a)))
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
typedef long long ll;
struct edge {
    int v,next;
} e[MAX*2];
int vis[MAX*2],pd[MAX*2];
int tot,cnt;
int head[MAX*2],flag;
void addedge(int u,int v) {
    e[tot].v=v;
    e[tot].next=head[u];
    head[u]=tot++;
}
void dfs(int u,int fa) {
    vis[u]=1;
    for(int i=head[u]; i!=-1; i=e[i].next) {
        int v=e[i].v;
        if(v==fa) continue;
        if(vis[v]) {
            flag=1;
            continue;
        }
        dfs(v,u);
    }
}
int ans=0;
void find(int n) {
    for(int i=1; i<=n; i++) {
        flag=0;
        if(!vis[i]) {//cout<<i<<endl;
            dfs(i,0);

            if(flag==0) ans++;
        }
    }
}
void init() {
    tot=0;
    flag=0;
    CLR(head,-1);
}
int main() {
    int t;
    int n,m,u,v;
    init();
    scanf("%d%d",&n,&m);
    for(int i=1; i<=m; i++) {
        scanf("%d%d",&u,&v);
        addedge(u,v);
        addedge(v,u);
    }
    find(n);
    cout<<ans<<endl;
    return 0;
}


F:将一个a变成矩阵b,要求:1.b中所有元素和=k;2.b中只有两种数0或x,x比a矩阵对应位置上的值小或等于;3.必须有一个x是a矩阵对应位置上的数。

我们可以先排个序,然后从大到小用并查集将四个方向上比当前大或等于的数放到一个集合,当这个集合满足条件就用bfs把所有的数搜出来。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
#include<vector>
#include<queue>
#include<cmath>
#include<stack>
#include<set>
#include<map>
#define INF 0x3f3f3f3f
#define Mn 1010
#define Mm 2010
#define mod 1000000007
#define CLR(a,b) memset((a),(b),sizeof((a)))
#define CPY(a,b) memcpy ((a), (b), sizeof((a)))
#pragma comment(linker, "/STACK:102400000,102400000")
#define ul u<<1
#define ur (u<<1)|1
using namespace std;
typedef long long ll;
struct node {
    int x,y,val;
    node(){}
    node(int x,int y,int val):x(x),y(y),val(val){}
}p[Mn*Mn];
int way[4][2]={0,-1,-1,0,0,1,1,0};
bool cmp(node a,node b) {
    return a.val>b.val;
}
int pre[Mn*Mn];
int num[Mn*Mn];
int find(int x) {
    return x==pre[x]?pre[x]:pre[x]=find(pre[x]);
}
void lin(int x,int y) {
    int a=find(x);
    int b=find(y);
    if(a!=b) {
        pre[a]=b;
        num[b]+=num[a];
        num[a]=0;
    }
}
int n,m;
int g[Mn][Mn];
void ol(int x,int y) {
    for(int i=0;i<4;i++) {
        int a=x+way[i][0];
        int b=y+way[i][1];
        if(a<0||b<0||a>=n||b>=m) continue;
        if(g[x][y]<=g[a][b]) {
            lin(a*m+b,x*m+y);
        }
    }
}
int vis[Mn][Mn];
queue<int> q;
void bfs(int st,int tot,int val) {
    q.push(st);
    while(!q.empty()) {
        int no=q.front();
        q.pop();
        int x=no/m;
        int y=no%m;
        if(vis[x][y]) continue;
        vis[x][y]=val;
        tot--;
        if(tot==0) break;
        for(int i=0;i<4;i++) {
            int a=x+way[i][0];
            int b=y+way[i][1];
            if(a<0||b<0||a>=n||b>=m||vis[a][b]) continue;
            if(val<=g[a][b]) {
               q.push(a*m+b);
            }
        }
    }
}
void prt() {
    printf("YES\n");
    for(int i=0;i<n;i++) {
        for(int j=0;j<m;j++)
            printf("%d ",vis[i][j]);
        printf("\n");
    }
}
int main() {
    int cnt=0;
    ll k;
    cin>>n>>m>>k;
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++) {
            scanf("%d",&g[i][j]);
            p[cnt++]=node(i,j,g[i][j]);
            pre[i*m+j]=i*m+j;
            num[i*m+j]=1;
        }
    sort(p,p+cnt,cmp);
    for(int i=0;i<cnt;i++) {
        ol(p[i].x,p[i].y);
        int tot=k/p[i].val;
        int pos=find(p[i].x*m+p[i].y);
        if((ll)num[pos]*p[i].val>=k&&k%p[i].val==0) {
            bfs(pos,tot,p[i].val);
            prt();
            return 0;
        }
    }
    printf("NO\n");
    return 0;
}


你可能感兴趣的:(Codeforces Round #346 (Div. 2))