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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
提供的源码资源涵盖了小程序应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值