codeforces 699

Problem A Launch of Collider

题目大意

  在x轴上有n个点,坐标均为偶数。每个点或向左移动或向右移动,每秒移动距离为1。

  使所有点同时开始移动,求最早有点相遇的时间或无解。

解题分析

  对于每一个向右移动的点,找右边最近的一个向左的点。向左移动同理。

  正反扫两遍即可。

参考程序

 1 #include <map>
 2 #include <set>
 3 #include <stack>
 4 #include <queue>
 5 #include <cmath>
 6 #include <ctime>
 7 #include <string>
 8 #include <vector>
 9 #include <cstdio>
10 #include <cstdlib>
11 #include <cstring>
12 #include <iostream>
13 #include <algorithm>
14 #pragma comment(linker,"/STACK:102400000,102400000")
15 using namespace std;
16
17 #define         N             200008
18 #define             V             1008
19 #define        E            60008
20 #define        lson                l,m,rt<<1
21 #define             rson                m,r+1,rt<<1|1
22 #define        clr(x,v)            memset(x,v,sizeof(x));
23 #define        LL            long long
24 //#define    debug
25 const int    mo        =        1000000007;
26 const int     inf        =        0x3f3f3f3f;
27 const int     INF       =        2000000000;
28 /**************************************************************************/
29 int n;
30 char s[N];
31 int a[N],ans[N];
32 int main(){
33     scanf("%d",&n);
34     scanf("%s",s+1);
35     for (int i=1;i<=n;i++) scanf("%d",&a[i]);
36     int x=-1;
37     for (int i=1;i<=n;i++)
38         if (s[i]==‘R‘) x=a[i];
39         else
40         {
41             if (x==-1) ans[i]=INF;
42             else ans[i]=(a[i]-x)/2;
43         }
44     x=-1;
45     for (int i=n;i>=1;i--)
46         if (s[i]==‘L‘) x=a[i];
47         else
48         {
49             if (x==-1) ans[i]=INF;
50             else ans[i]=(x-a[i])/2;
51         }
52     int res=INF;
53     for (int i=1;i<=n;i++) res=min(res,ans[i]);
54     printf("%d\n",res==INF ? -1 : res);
55
56     #ifdef debug
57     system("pause");
58     #endif
59 }
60                         

Problem B One Bomb

题目大意

  有一个n*m的矩形,每一个格子为空地或者为墙壁。 (n,m<=1000)

  现在要某点放置一颗炸弹,炸掉所有的墙壁。炸弹的爆炸范围为该点的上下左右两条直线。

  给出一种方案或无解。

解题分析

  记录一下每行的墙壁数,每列的墙壁数。

  枚举每个点是否放置炸弹即可。

参考程序

 1 #include <map>
 2 #include <set>
 3 #include <stack>
 4 #include <queue>
 5 #include <cmath>
 6 #include <ctime>
 7 #include <string>
 8 #include <vector>
 9 #include <cstdio>
10 #include <cstdlib>
11 #include <cstring>
12 #include <iostream>
13 #include <algorithm>
14 #pragma comment(linker,"/STACK:102400000,102400000")
15 using namespace std;
16
17 #define             N             1000008
18 #define             V             1008
19 #define        E            60008
20 #define        lson                l,m,rt<<1
21 #define             rson                m,r+1,rt<<1|1
22 #define        clr(x,v)            memset(x,v,sizeof(x));
23 #define        LL            long long
24 //#define     debug
25 const int    mo    =    1000000007;
26 const int     inf =    0x3f3f3f3f;
27 const int     INF =    2000000000;
28 /**************************************************************************/
29
30 int n,m,num;
31 int x[V],y[V],mp[V][V];
32 int main(){
33     scanf("%d%d",&n,&m);
34     num=0;
35     for (int i=1;i<=n;i++){
36         char s[V];
37         scanf("%s",s+1);
38         for (int j=1;j<=m;j++)
39             if (s[j]==‘*‘){
40                 x[i]++;
41                 y[j]++;
42                 mp[i][j]=1;
43                 num++;
44             }
45     }
46     int ok=0;
47     int tx,ty;
48     for (tx=1;tx<=n;tx++){
49         for (ty=1;ty<=m;ty++){
50             int now;
51             if (mp[tx][ty]) now=x[tx]+y[ty]-1; else now=x[tx]+y[ty];
52             if (now==num){
53                 ok=1;
54                 break;
55             }
56         }
57         if (ok) break;
58     }
59     if (ok) printf("YES\n%d %d\n",tx,ty); else printf("NO\n");
60
61     #ifdef debug
62     system("pause");
63     #endif
64 }                

Problem C Vacations

题目大意

  一个小朋友每天可以选择休息或者网上打比赛或者去体育馆玩,但不能两天都刷题或者都玩耍。

  给定每天是否网上有比赛,体育馆是否开。

  问小朋友n天内最少需要休息几天。

解题分析

  dp[i][0~2] 表示第i天干某事的最少休息天数。

  分情况讨论转移。

参考程序

 1 #include <map>
 2 #include <set>
 3 #include <stack>
 4 #include <queue>
 5 #include <cmath>
 6 #include <ctime>
 7 #include <string>
 8 #include <vector>
 9 #include <cstdio>
10 #include <cstdlib>
11 #include <cstring>
12 #include <iostream>
13 #include <algorithm>
14 #pragma comment(linker,"/STACK:102400000,102400000")
15 using namespace std;
16
17 #define         N             100008
18 #define         V             1008
19 #define        E            60008
20 #define        lson                l,m,rt<<1
21 #define             rson                m,r+1,rt<<1|1
22 #define        clr(x,v)            memset(x,v,sizeof(x));
23 #define        LL            long long
24 //#define     debug
25 const int    mo    =    1000000007;
26 const int     inf =    0x3f3f3f3f;
27 const int     INF =    2000000000;
28 /**************************************************************************/
29 int min(int x,int y,int z){
30     if (x<=y && x<=z) return x;
31     if (y<=x && y<=z) return y;
32     if (z<=x && z<=y) return z;
33 }
34 int dp[N][3],ok[N][3];
35 int n;
36 int main(){
37     scanf("%d",&n);
38     for (int i=1;i<=n;i++){
39         int x;
40         scanf("%d",&x);
41         if (x==0){
42             ok[i][0]=1;
43             ok[i][1]=0;
44             ok[i][2]=0;
45         }
46         if (x==1){
47             ok[i][0]=1;
48             ok[i][1]=0;
49             ok[i][2]=1;
50         }
51         if (x==2){
52             ok[i][0]=1;
53             ok[i][1]=1;
54             ok[i][2]=0;
55         }
56         if (x==3){
57             ok[i][0]=1;
58             ok[i][1]=1;
59             ok[i][2]=1;
60         }
61     }
62     for (int i=1;i<=n;i++){
63         if (ok[i][0]){
64             dp[i][0]=min(dp[i-1][0],dp[i-1][1],dp[i-1][2])+1;
65         }
66         else dp[i][0]=INF;
67         if (ok[i][1]){
68             dp[i][1]=min(dp[i-1][0],dp[i-1][2]);
69         }
70         else dp[i][1]=INF;
71         if (ok[i][2]){
72             dp[i][2]=min(dp[i-1][0],dp[i-1][1]);
73         }
74         else dp[i][2]=INF;
75     }
76     printf("%d\n",min(dp[n][0],dp[n][1],dp[n][2]));
77     #ifdef debug
78     system("pause");
79     #endif
80 }            

Problem D Fix a tree

题目大意

  有n个点,给定一个序列f[i]表示i号点的父亲为f[i]。

  要求改变最少的f[i],使得这n个点形成一棵树。

解题分析

  从每个为搜索过的点开始沿着f[i]开始搜索,如果与之前的点形成了环,说明这些点形成了一个连通块,若形成的环不是自环,则环中的某个点需要改变f[i],从而形成一棵树。

  处理出所有的联通块后,假设有x个。

  若其中的某个连通块的有自环j,则需改变x-1次,将其他连通块中的某个环中点f[i]改为j。

  若没有自环,则需改变x次,将某个环中点改为自环,其他同上处理。

参考程序

 1 #include <map>
 2 #include <set>
 3 #include <stack>
 4 #include <queue>
 5 #include <cmath>
 6 #include <ctime>
 7 #include <string>
 8 #include <vector>
 9 #include <cstdio>
10 #include <cstdlib>
11 #include <cstring>
12 #include <iostream>
13 #include <algorithm>
14 #pragma comment(linker,"/STACK:102400000,102400000")
15 using namespace std;
16
17 #define             N             200008
18 #define             V             200008
19 #define        E            60008
20 #define        lson                    l,m,rt<<1
21 #define             rson                m,r+1,rt<<1|1
22 #define        clr(x,v)            memset(x,v,sizeof(x));
23 #define        LL            long long
24 //#define     debug
25 const int    mo    =    1000000007;
26 const int     inf =    0x3f3f3f3f;
27 const int     INF =    2000000000;
28 /**************************************************************************/
29 int n,tmp,lx=0;
30 int f[V],dfn[V],instack[V];
31 int ans[V];
32 void dfs(int x){
33     if (dfn[x]){
34         if (instack[x]==lx) ans[++ans[0]]=x;
35         return;
36     }
37     instack[x]=lx;
38     dfn[x]=++tmp;
39     dfs(f[x]);
40 }
41 int main(){
42     scanf("%d",&n);
43     for (int i=1;i<=n;i++) scanf("%d",&f[i]);
44
45     for (int i=1;i<=n;i++){
46         lx++;
47         if (!dfn[i]) dfs(i);
48     }
49     lx=-1;
50     for (int i=1;i<=ans[0];i++)
51         if (f[ans[i]]==ans[i]) lx=ans[i];
52     if (lx==-1){
53         printf("%d\n",ans[0]);
54         for (int i=1;i<ans[0];i++)
55             f[ans[i]]=ans[i+1];
56         f[ans[ans[0]]]=ans[ans[0]];
57     }
58     else
59     {
60         printf("%d\n",ans[0]-1);
61         for (int i=1;i<=ans[0];i++)
62             f[ans[i]]=lx;
63     }
64     for (int i=1;i<=n;i++) printf("%d%c",f[i],i==n?‘\n‘:‘ ‘);
65
66     #ifdef debug
67     system("pause");
68     #endif
69 }

 

时间: 2024-10-06 02:57:33

codeforces 699的相关文章

【模拟】Codeforces 699B One Bomb

题目链接: http://codeforces.com/problemset/problem/699/B 题目大意: N*M的图,*代表墙.代表空地.问能否在任意位置(可以是墙上)放一枚炸弹(能炸所在行和列),把所有的墙都炸掉.输出答案(不唯一). 题目思路: [模拟] N2预处理出每一行能炸多少墙,每一列能炸多少墙.再N2枚举放炸弹的位置看能炸掉的墙数目是否等于总数.注意如果炸弹位置上有墙要-1. 1 // 2 //by coolxxx 3 ////<bits/stdc++.h> 4 #in

【动态规划】Codeforces 699C Vacations

题目链接: http://codeforces.com/problemset/problem/699/C 题目大意: N天,A(健身)或B(做比赛)或休息,每天都有4种情况,A可行B可行,A可行B不行,A不行B可行,AB都不行. 每天选择一种,不能连续两天选择同一种活动(可以连续休息),问最少休息几天. 题目思路: [动态规划] f[i][j]表示前i天,最后一天状态为j的最多休息天数(最少天数也行),j=0,1,2表示休息,运动和做比赛. 转移方程挺好推的. 1 // 2 //by coolx

【并查集】【模拟】Codeforces 699D Fix a Tree

题目链接: http://codeforces.com/problemset/problem/699/D 题目大意: 通过给定当前节点的父亲给你一棵有错的树,可能有多个根和环,输出改成正确的一棵树至少要修改几个节点的父亲和修改后所有点的父亲值 题目思路: [并查集][模拟] 用并查集把成环的归在一起(类似强连通分量),然后统计分量数并修改. 第一个出现的当作根,其余的每一块连通分量都去掉一条边改为连接到根上. 1 // 2 //by coolxxx 3 ////<bits/stdc++.h>

codeforces #363(div.2)

A题 http://codeforces.com/problemset/problem/699/A 非常的水,两个相向而行,且间距最小的点,搜一遍就是答案了. 1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 struct node 5 { 6 int x;char ch; 7 }s[200000+50]; 8 bool cmp(node& a,node& b) 9 { 10 re

【模拟】Codeforces 699A Launch of Collider

题目链接: http://codeforces.com/problemset/problem/699/A 题目大意: 给N个点,向左或向右运动,速度均为1,问最早什么时候有两个点相撞.无解输出-1 题目思路: [模拟] 模拟一下,记录往左往右的位置即可. 1 // 2 //by coolxxx 3 ////<bits/stdc++.h> 4 #include<iostream> 5 #include<algorithm> 6 #include<string>

【codeforces 718E】E. Matvey&#39;s Birthday

题目大意&链接: http://codeforces.com/problemset/problem/718/E 给一个长为n(n<=100 000)的只包含‘a’~‘h’8个字符的字符串s.两个位置i,j(i!=j)存在一条边,当且仅当|i-j|==1或s[i]==s[j].求这个无向图的直径,以及直径数量. 题解:  命题1:任意位置之间距离不会大于15. 证明:对于任意两个位置i,j之间,其所经过每种字符不会超过2个(因为相同字符会连边),所以i,j经过节点至多为16,也就意味着边数至多

Codeforces 124A - The number of positions

题目链接:http://codeforces.com/problemset/problem/124/A Petr stands in line of n people, but he doesn't know exactly which position he occupies. He can say that there are no less than a people standing in front of him and no more than b people standing b

Codeforces 841D Leha and another game about graph - 差分

Leha plays a computer game, where is on each level is given a connected graph with n vertices and m edges. Graph can contain multiple edges, but can not contain self loops. Each vertex has an integer di, which can be equal to 0, 1 or  - 1. To pass th

Codeforces Round #286 (Div. 1) A. Mr. Kitayuta, the Treasure Hunter DP

链接: http://codeforces.com/problemset/problem/506/A 题意: 给出30000个岛,有n个宝石分布在上面,第一步到d位置,每次走的距离与上一步的差距不大于1,问走完一路最多捡到多少块宝石. 题解: 容易想到DP,dp[i][j]表示到达 i 处,现在步长为 j 时最多收集到的财富,转移也不难,cnt[i]表示 i 处的财富. dp[i+step-1] = max(dp[i+step-1],dp[i][j]+cnt[i+step+1]) dp[i+st