Codeforces Wunder fund 618ABCDEF

Codeforces Wunder fund
题目链接:http://codeforces.com/contest/618
最后一题过了12个人就不改了……
通过数 3
Standing: 506/6671
Rating change: 1811 - 1862
ABC忘记什么题了。

A:
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <string>
#include <algorithm>
#include <iostream>
using namespace std;
int a[60];
int main()
{
    int n;
    while(scanf("%d", &n) != EOF){
        int now = 0;
        int cnt = 0;
        int num = 0;
        while((1 << now) <= n){
            if((1 << now) & n) a[cnt++] = num + 1;
            num++;
            now++;
        }
        for(int i = cnt - 1 ; i >= 0 ; i--){
            printf("%d", a[i]);
            if(i == 0) printf("\n");
            else printf(" ");
        }
    }
    return 0;
}

B:
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <string>
#include <algorithm>
#include <iostream>
using namespace std;
const int MAXN = 50 + 5;
int g[MAXN][MAXN];
int use[MAXN], ans[MAXN];
int cnt[MAXN];
int main()
{
    int n;
    while(scanf("%d", &n) != EOF){
        memset(ans, 0, sizeof(ans));
        memset(use, 0, sizeof(use));
        for(int i = 1 ; i <= n ; i++) for(int j = 1 ; j <= n ; j++) scanf("%d", &g[i][j]);
        for(int i = 1 ; i <= n ; i++){
            for(int j = 1 ; j <= n ; j++) cnt[j] = 0;
            for(int j = 1 ; j <= n ; j++) cnt[g[i][j]]++;
            for(int j = 1 ; j <= n ; j++){
                if(cnt[j] > 1){
                    ans[i] = j;
                    use[j] = 1;
                    break;
                }
            }
        }

        int head = 1;
        for(int i = 1 ; i <= n ; i++){
            if(ans[i] == 0){
                while(use[head] == 1) head++;
                ans[i] = head;
                use[head] = 1;
            }
        }

        for(int i = 1 ; i <= n ; i++){
            printf("%d", ans[i]);
            if(i == n) printf("\n");
            else printf(" ");
        }
    }
    return 0;
}

C:
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <string>
#include <algorithm>
#include <iostream>
#include <map>
using namespace std;
const int MAXN = 100000 + 5;
struct D
{
    int x, y;
    int id;
}d[MAXN];
bool cmp(D a, D b)
{
    if(a.x == b.x) return a.y < b.y;
    return a.x < b.x;
}
bool cal(int u1, int v1, int u2, int v2, int u3, int v3)
{
    long long t1 = v1 - v2;
    t1 = t1 * (u1 - u3);
    long long t2 = v1 - v3;
    t2 = t2 * (u1 - u2);
//    printf("t1 = %I64d, t2 = %I64d\n", t1, t2);
    if(t1 == t2) return true;
    else return false;
}
int main()
{
    int n;
    while(scanf("%d", &n) != EOF){
        for(int i = 1 ; i <= n ; i++){
            scanf("%d%d", &d[i].x, &d[i].y);
            d[i].id = i;
        }
        sort(d + 1, d + 1 + n, cmp);
//        for(int i = 1 ; i <= n ; i++){
//            printf("x = %d, y = %d, id = %d\n", d[i].x, d[i].y, d[i].id);
//        }
        int rx1 = d[1].x, ry1 = d[1].y;
        int rx2, ry2;
        int f = 1;
        int a1 = d[1].id, a2, a3;
        for(int i = 2 ; i <= n ; i++){
            if(f){
                rx2 = d[i].x, ry2 = d[i].y;
                f = 0;
                a2 = d[i].id;
            }
            else{
                if(cal(rx1, ry1, rx2, ry2, d[i].x, d[i].y)) continue;
                else{
                    a3 = d[i].id;
                    break;
                }
            }
        }
        printf("%d %d %d\n", a1, a2, a3);
    }
    return 0;
}

D:
给一个完全图,图中边有权值,其中给出的一颗生成树上的边权值为x,非此树上的边权值为y。
求不重复的走完所有点的最小代价。

赛中猜测是分类讨论。
X>y的时候不知道怎么考虑,随便写了一发。
X

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <string>
#include <algorithm>
#include <iostream>
#include <map>
#include <vector>
#include <queue>
using namespace std;
#define LL long long
const int MAXN = 200000 + 5;
vector<int>lin[MAXN];
queue<int>que;
int du[MAXN];
int vis[MAXN];
int n;
LL x, y;
int dfs(int u, int pre, int &cnt)
{
    int temp = 0;
    for(int i = 0 ; i < (int)lin[u].size() ; i++){
        int v = lin[u][i];
        if(v == pre) continue;
        if(dfs(v, u, cnt)) temp++;
    }
    if(u == 1){
        cnt += max(temp - 2, 0);
        return 0;
    }
    else{
        if(temp > 1){
            cnt += temp - 1;
            return 0;
        }
        else return 1;
    }
}
LL solve1()
{
    for(int i = 1 ; i <= n ; i++){
        if(du[i] == 1){
            que.push(i);
            vis[i] = 1;
            break;
        }
    }
    int cnt = 0;
    dfs(1, -1, cnt);
//    printf("cnt = %d\n", cnt);
    return x * (n - 1 - cnt) + y * cnt;
}
LL solve2()
{
    int cnt = 0;
    for(int i = 1 ; i <= n ; i++){
        if(du[i] == n - 1){
            cnt++;
            break;
        }
    }
    return y * (n - 1 - cnt) + x * cnt;
}
int main()
{
    while(scanf("%d%I64d%I64d", &n, &x, &y) != EOF){
        int u, v;
        for(int i = 1 ; i <= n ; i++) lin[i].clear() ,vis[i] = du[i] = 0;
        while(!que.empty()) que.pop();
        for(int i = 0 ; i < n - 1 ; i++){
            scanf("%d%d", &u, &v);
            lin[u].push_back(v);
            lin[v].push_back(u);
            du[u]++;
            du[v]++;
        }
        for(int i = 1 ; i <= n ; i++) sort(lin[i].begin(), lin[i].end());
        LL ans = 0;
        if(x == y){
            ans = x * (n - 1);
        }
        else if(x < y){
            ans = solve1();
        }
        else ans = solve2();
        printf("%I64d\n", ans);
    }
    return 0;
}

E:
赛中听老耿说是计算几何没看,实际上是线段树。
线段树我也不会啊……
先导题POJ 2991,然后这题就很简单了。

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <string>
#include <algorithm>
#include <iostream>
#include <vector>
#include <map>
using namespace std;
const int MAXN = 300000 + 5;
const double PI = acos(-1.0);
int n, m;
double x[MAXN * 4], y[MAXN * 4];
int angle[MAXN * 4], flag[MAXN * 4];
void func(int o, int ang)
{
    double tx = x[o], ty = y[o];
    x[o] = ty * sin(ang * PI / 180.0) + tx * cos(ang * PI / 180.0);
    y[o] = ty * cos(ang * PI / 180.0) - tx * sin(ang * PI / 180.0);
    flag[o] = (flag[o] + ang) % 360;
    angle[o] = (angle[o] + ang) % 360;
}
void push_up(int o)
{
    x[o] = x[o << 1] + x[o << 1 | 1];
    y[o] = y[o << 1] + y[o << 1 | 1];
}
void push_down(int o)
{
    if(flag[o]){
        func(o << 1, flag[o]);
        func(o << 1 | 1, flag[o]);
        flag[o] = 0;
    }
}
void build(int l, int r, int o)
{
    x[o] = y[o] = 0;
    angle[o] = 90;
    flag[o] = 0;
    if(l == r){
        x[o] = 1;
    }
    else{
        int mid = (l + r) >> 1;
        build(l, mid, o << 1);
        build(mid + 1, r, o << 1 | 1);
        push_up(o);
    }
}
void update1(int u, int v, int L, int R, int o)
{
    if(L == R){
        x[o] = x[o] + v * sin(angle[o] * PI / 180.0);
        y[o] = y[o] + v * cos(angle[o] * PI / 180.0);
    }
    else{
        push_down(o);
        int mid = (L + R) >> 1;
        if(u <= mid) update1(u, v, L, mid, o << 1);
        else update1(u, v, mid + 1, R, o << 1 | 1);
        push_up(o);
    }
}
void update2(int l, int r, int v, int L, int R, int o)
{
    if(l <= L && r >= R){
        func(o, v);
    }
    else{
        push_down(o);
        int mid = (L + R) >> 1;
        if(l <= mid) update2(l, r, v, L, mid, o << 1);
        if(mid < r) update2(l, r, v, mid + 1, R, o << 1 | 1);
        push_up(o);
    }
}
int main()
{
//    freopen("CF 618E.in", "r", stdin);
    while(scanf("%d%d", &n, &m) != EOF){
        build(1, n, 1);
//        printf("x[1] = %f, y[1] = %f\n", x[1], y[1]);
        for(int i = 1 ; i <= m ; i++){
            int op, u, v;
            scanf("%d%d%d", &op, &u, &v);
            if(op == 1){
                update1(u, v, 1, n, 1);
            }
            else{
                update2(u, n, v, 1, n, 1);
            }
            printf("%.10f %.10f\n", x[1], y[1]);
        }
    }
    return 0;
}

F:
两个序列,任取数使得两个序列取出的数和相等。
感觉是很重要的模型。
/*
容斥原理中的鸽笼原理。
因为前缀和是递增的,记录值SumOfa - SumOfb,其中SumOfb为小于等于SumOfa的最大值
然后由于每个数都属于[1,n - 1],所以这个值的范围[0,n - 1]。
因为一共有n+1中取法(包括不取任意一个数,视为SumOfa - SumOfb = 0)
故必定有两个差值相等
然后看代码就知道了
*/

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <string>
#include <algorithm>
#include <iostream>
#include <vector>
#include <utility>
using namespace std;
#define LL long long
const int MAXN = 1000000 + 5;
int a[MAXN], b[MAXN];
pair<int,int> vis[MAXN];
vector<int>o1, o2;
int main()
{
    int n;
    while(scanf("%d", &n) != EOF){
        for(int i = 1 ; i <= n ; i++) scanf("%d", &a[i]);
        for(int i = 1 ; i <= n ; i++) scanf("%d", &b[i]);
        for(int i = 0 ; i <= n ; i++) vis[i] = make_pair(-1, -1);
        vis[0] = make_pair(0, 1);
        int head = 1;
        LL s1 = 0, s2 = 0;
        o1.clear(), o2.clear();
        for(int i = 1 ; i <= n ; i++){
            s1 += a[i];
            while(head <= n && s2 + b[head] <= s1) s2 += b[head++];
            int mark = s1 - s2;
//            printf("mark = %d, i = %d, head = %d\n")
            if(vis[mark].first == -1) vis[mark] = make_pair(i, head);
            else{
                for(int j = vis[mark].first + 1; j <= i ; j++) o1.push_back(j);
                for(int j = vis[mark].second; j <= head - 1; j++) o2.push_back(j);
//                printf("vis[mark] = %d %d, i = %d, head = %d\n", vis[mark].first, vis[mark].second, i, head);
//                printf("s1 = %I64d, s2 = %I64d\n", s1, s2);
                break;
            }
        }
        printf("%d\n", (int)o1.size());
        for(int i = 0 ; i < (int)o1.size() ; i++){
            printf("%d", o1[i]);
            if(i == (int)o1.size() - 1) printf("\n");
            else printf(" ");
        }

        printf("%d\n", (int)o2.size());
        for(int i = 0 ; i < (int)o2.size() ; i++){
            printf("%d", o2[i]);
            if(i == (int)o2.size() - 1) printf("\n");
            else printf(" ");
        }
    }
    return 0;
}
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。、可私 6信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。、可 6私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。、可私 6信博主看论文后选择购买源代码。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值