Educational Codeforces Round 27 补题

题目链接:http://codeforces.com/contest/845

A. Chess Tourney

水题,排序之后判断第n个元素和n+1个元素是不是想等就可以了。

#include <bits/stdc++.h>
using namespace std;
int a[210];
int n;
int main()
{
    scanf("%d", &n);
    for(int i=1; i<=2*n; i++) scanf("%d", &a[i]);
    sort(a+1,a+2*n+1,greater<int>());
    if(a[n]!=a[n+1])
    puts("YES");
    else puts("NO");
    return 0;
}

 B. Luba And The Ticket

题意:给了一个只有6个字母的字符串,然后问最少改变几个数字,使得前3个数字的和等于后3个数字的和。

解法:直接暴力枚举这6位数字会变成什么,在满足条件下维护最小值。

#include <bits/stdc++.h>
using namespace std;
int a[10];
char s[10];

int main()
{
    scanf("%s", s+1);
    for(int i=1; i<=6; i++){
        a[i] = s[i]-'0';
    }
    int ans = 100;
    for(int i=0; i<10; i++){
        for(int j=0; j<10; j++){
            for(int k=0; k<10; k++){
                for(int x=0; x<10; x++){
                    for(int y=0; y<10; y++){
                        for(int z=0; z<10; z++){
                            if(i+j+k==x+y+z){
                               int cnt = 0;
                               if(i!=a[1]) cnt++;
                               if(j!=a[2]) cnt++;
                               if(k!=a[3]) cnt++;
                               if(x!=a[4]) cnt++;
                               if(y!=a[5]) cnt++;
                               if(z!=a[6]) cnt++;
                               ans = min(ans, cnt);
                            }
                        }
                    }
                }
            }
        }
    }
    printf("%d\n", ans);
}

 C. Two TVs

题意:有n个电视节目,每个节目有一个开始的播放时间和结束的播放时间,现在有2台电视可以同时播放节目,但是有重合时间点的节目不能在同一台电视播放,问是否可以通过安排播放顺序让所有的节目都被播放完。

解法:一个显然的贪心,按l,r从小到大排序之后,分别往第一个和第二个电视结束时间最早的那个放就OK了。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5+5;
struct node{
    int l,r;
    node(){}
    bool operator<(const node &rhs) const{
        if(l == rhs.l) return r<rhs.r;
        return l<rhs.l;
    }
}a[maxn];
int en1, en2;

int main()
{
    int n;
    scanf("%d", &n);
    for(int i=1; i<=n; i++){
        scanf("%d %d", &a[i].l,&a[i].r);
    }
    sort(a+1,a+n+1);
    en1 = -1, en2 = -1;
    for(int i=1; i<=n; i++){
        if(a[i].l > en1 && a[i].l > en2){
            if(en1 > en2){
                en2 = a[i].r;
            }
            else{
                en1 = a[i].r;
            }
        }
        else if(a[i].l > en1){
            en1 = a[i].r;
        }
        else if(a[i].l > en2){
            en2 = a[i].r;
        }
        else{
            puts("NO");
            return 0;
        }
    }
    puts("YES");
    return 0;
}

 D. Driving Test

题意:给出n次操作,你可以忽略 可以超车,不可以超车,速度最大限制以及无速度限制这些操作,问使得超车以及改变速度合法的前提下最少需要忽略多少次操作,每次超车可以覆盖前面所有的超车和不超车,速度最大限制和无速度限制一样。

解法:直接模拟即可。

#include <bits/stdc++.h>
using namespace std;

int main()
{
    int n,op,x,now=0,lim=0,cnt=0;
    vector<int>v;
    scanf("%d", &n);
    for(int i=1; i<=n; i++){
        scanf("%d", &op);
        if(op == 1){
            scanf("%d", &x);
            now=x;
            while(!v.empty() && now>v.back()){
                v.pop_back();
                cnt++;
            }
        }
        if(op == 2){
            cnt += lim;
            lim = 0;
        }
        if(op == 3){
            scanf("%d", &x);
            v.push_back(x);
            while(!v.empty() && now>v.back()){
                v.pop_back();
                cnt++;
            }
        }
        if(op == 4){
            lim = 0;
        }
        if(op == 5){
            v.clear();
        }
        if(op == 6){
            lim++;
        }
    }
    printf("%d\n", cnt);
    return 0;
}

 E:

F:

G. Shortest Path Problem?

题意:这道题要求从1到n的最小xor和路径,存在重边,允许经过重复点、重复边。

解法:线形基,BZOJ原题,BZOJ 2115 不过那道题求的是最大值,这个题求的是最小值。

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 100010;
const int maxm = 500010;
int n, m, edgecnt;
int head[maxn];
bool vis[maxn];
LL dx[maxn];
LL p[70];
LL circle[maxm], ans;
void init(){
    memset(head, -1, sizeof(head));
    edgecnt = 0;
}
struct edge{
    int to,next;
    LL w;
    edge(){}
    edge(int to, int next, LL w):to(to),next(next),w(w){}
}E[maxm];
int cnt = 0;
void add(int u, int v, LL w){
    E[edgecnt].to = v, E[edgecnt].next = head[u], E[edgecnt].w = w, head[u] = edgecnt++;
}
void dfsloop(int x){
    vis[x] = 1;
    for(int i=head[x]; i+1; i=E[i].next){
        int to = E[i].to;
        if(!vis[to]) dx[to] = dx[x]^E[i].w, dfsloop(to);
        else{
            circle[++cnt] = dx[to]^dx[x]^E[i].w;
        }
    }
}

int main()
{
    int x,y;
    LL z;
    init();
    scanf("%d %d", &n,&m);
    for(int i=1; i<=m; i++){
        scanf("%d %d %lld", &x,&y,&z);
        add(x, y, z);
        add(y, x, z);
    }
    dfsloop(1);
    ans = dx[n];//任取一条从1到n的路径,并得到其xor和
    for(int i=1; i<=cnt; i++){
        for(int j=62; j>=0; j--){
            if(!(circle[i]>>j)) continue;
            if(!p[j]){
                p[j] = circle[i];
                break;
            }
            circle[i] ^= p[j];
        }
    }
     //for(int i=62;i>=0;i--) if(!(ans>>i)) ans^=p[i];
     //ans有初值,不能直接根据这一位是否为0来判断是否更大,max更为稳妥
     for(int i=62; i>=0; i--){
        if((ans^p[i])<ans){
            ans = ans^p[i];
        }
     }
     printf("%lld\n", ans);
     return 0;
}

 

posted @ 2017-08-29 20:17  zxycoder  阅读(147)  评论(0编辑  收藏  举报