Codeforces Round #303 (Div. 2)

来源:互联网 发布:张大奕有几个淘宝店 编辑:程序博客网 时间:2024/05/21 04:21

A.Toy Cars

原题:http://codeforces.com/contest/545/problem/A

题意:

有n辆车,给出n*n的矩阵;

a[i][j] = 1表示第i辆车坏, = 2表示第j辆车坏,  = 3表示第i, j辆车都坏;

问好的车有几辆;


#include<stdio.h>#include<string.h>int n;int arr[110][110], ans[110];bool res[110];int main(){while(scanf("%d", &n)!=EOF){int sum = 0;memset(res, false, sizeof res);for(int i = 1;i<=n;i++){for(int j = 1;j<=n;j++){scanf("%d", &arr[i][j]);if(arr[i][j] == 1)res[i] = true;if(arr[i][j] == 2)res[j] = true;if(arr[i][j] == 3){res[i] = true;res[j] = true;}}}int k = 0;for(int i = 1;i<=n;i++){if(!res[i]){sum++;ans[k++] = i;}}printf("%d\n", sum);for(int i = 0;i<k;i++){if(i == k-1)printf("%d\n", ans[i]);elseprintf("%d ", ans[i]);}}return 0;}




B.Equidistant String

原题:http://codeforces.com/contest/545/problem/B
题意:有s1、s2两个字符串,均由01构成;
问能否得到第三个01串c,使得它和给定的两个字符串差值相等,输出满足条件的任意答案即可;
所谓的差值就是各位上的差之和;

思路:
先比较s1、s2,计算两者不同的位置有几个,若是奇数,直接输出impossible;
将不同的位置的个数对半分,在c中,前一半输出s1[i],后一半输出s2[i];



#include<stdio.h>#include<string.h>char s1[100005];char s2[100005];int main(){while(scanf("%s%s", s1, s2)!=EOF){int len = strlen(s1);int sum = 0;for(int i = 0;i<len;i++){if(s1[i]!=s2[i])sum++;}if(sum%2 == 1)printf("impossible\n");else{sum/=2;for(int i = 0;i<len;i++){if(s1[i]!=s2[i]){if(sum){printf("%c", s1[i]);sum--;}elseprintf("%c", s2[i]);}elseprintf("%c", s1[i]);}printf("\n");}}return 0;}




C.Woodcutters


题意:
给出n棵树的位置x和高度h;
每棵树可以往右倒或者往左倒,但区间必须大于树的高度;
问最多可以砍到几棵树;

思路:
第一棵树肯定往左倒;其他的树左右区间判断一下;


#include<stdio.h>int n;struct node{int x, h;}tree[100005];int main(){while(scanf("%d", &n)!=EOF){int sum;if(n>=2)sum = 2;elsesum = 1;for(int i = 1;i<=n;i++)scanf("%d%d", &tree[i].x, &tree[i].h);for(int i = 2;i<n;i++){int l1 = tree[i].x-tree[i-1].x;int l2 = tree[i+1].x-tree[i].x;if(tree[i].h<l1)sum++;else{if(tree[i].h<l2){sum++;tree[i].x+=tree[i].h;<span style="white-space:pre"></span>//如果向右倒,区间值相应的要改变;}}}printf("%d\n", sum);}return 0;}



D.Queue

原题:http://codeforces.com/contest/545/problem/D
题意:
给出n个人的服务时间;
如果某人的等待时间超过服务时间就不能让该人满意;
问一共可以让多少人满意;

思路:
排序,然后时间累加判断;


#include<stdio.h>#include<algorithm>using namespace std;int n;int arr[100005];int main(){while(scanf("%d", &n)!=EOF){for(int i = 0;i<n;i++)scanf("%d", &arr[i]);sort(arr, arr+n);int sum = 0;int ans = 0;for(int i = 0;i<n;i++){if(arr[i]>=sum){sum+=arr[i];ans++;}}printf("%d\n", ans);}return 0;}



E.Paths and Trees


原题:http://codeforces.com/contest/545/problem/E
题意:
给定一个带权无向图;
选取一些边建立一个新图(节点不变),使得起点st到其他点的距离最短,当最短路相同时选择权值小的边;

思路:
用spfa 跑最短路,当最短距离一样时比较边权;



#include<stdio.h>#include<queue>#include<string.h>#include<algorithm>using namespace std;typedef long long ll;const int maxn = 300005;const ll inf = 1e16;int n, m, st;bool vis[maxn];int num, head[maxn];int pre[maxn], val[maxn];<span style="white-space:pre"></span>//pre[]记录选择的边,val[]记录每条边的权值;ll dis[maxn];struct node{int v, w, id, next;}edge[maxn<<1];void init(){num = 0;memset(head, -1, sizeof head);}void add(int u, int v, int w, int id){edge[num].v = v;edge[num].w = w;edge[num].id = id;edge[num].next = head[u];head[u] = num++;}void spfa(){queue<int>Q;for(int i = 1;i<=n;i++)dis[i] = inf;memset(vis, false, sizeof vis);memset(pre, 0, sizeof pre);dis[st] = 0, vis[st] = true;Q.push(st);while(!Q.empty()){int u = Q.front();Q.pop();vis[u] = false;for(int i = head[u];i!=-1;i = edge[i].next){int v = edge[i].v;if(dis[v]>dis[u]+edge[i].w){dis[v] = dis[u]+edge[i].w;pre[v] = edge[i].id;if(!vis[v]){vis[v] = true;Q.push(v);}}else if(dis[v] == dis[u]+edge[i].w){if(edge[i].w<val[pre[v]]){pre[v] = edge[i].id;if(!vis[v]){vis[v] = true;Q.push(v);}}}}}}int main(){while(scanf("%d%d", &n, &m)!=EOF){init();ll ans = 0;for(int i = 1;i<=m;i++){int u, v, w;scanf("%d%d%d", &u, &v, &w);add(u, v, w, i);add(v, u, w, i);val[i] = w;}scanf("%d", &st);spfa();for(int i = 1;i<=n;i++){if(pre[i])ans+=val[pre[i]];}printf("%I64d\n", ans);for(int i = 1;i<=n;i++){if(pre[i])printf("%d ", pre[i]);}printf("\n");}return 0;}





0 0
原创粉丝点击