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     return a.x<b.x;
11 }
12 int main()
13 {
14     int n;
15     while(~scanf("%d",&n))
16     {
17         getchar();
18         for(int i=0;i<n;i++)
19             scanf("%c",&s[i].ch);
20         for(int i=0;i<n;i++)
21             scanf("%d",&s[i].x);
22         sort(s,s+n,cmp);
23         int ans = 0x3f3f3f3f;
24         for(int i=1;i<n;i++)
25         {
26             if(s[i].ch == ‘L‘ && s[i-1].ch == ‘R‘)
27             {
28                 int dis= (s[i].x - s[i-1].x)/2;
29                 ans = min(ans,dis);
30             }
31         }
32         if(ans == 0x3f3f3f3f)
33             printf("-1\n");
34         else
35             printf("%d\n",ans);
36     }
37     return 0;
38 }

B题 http://codeforces.com/problemset/problem/699/B

讲道理 也是水题 然而我在实现的时候 实现不好这个问题 然而梦天2333 毕竟天神啪啪啪随便写写就A了。

这个代码是参考网上的思路搞的,关键是一个V数组和一个C数组记录,行和列的情况。

还有读入字符串的时候要小心的,因为它题目中默认的地图是从1开始的,如果直接scanf ma[i]这样读进来 就是每行都从0开始了,和题意不符

1 scanf("%s",ma[i]+1);//输入的一个小技巧

其实思路和它标程是一样的,就是没码出来。

 1 #include <cstdio>
 2 #include <cstring>
 3 #define mem0(x) memset(x,0,sizeof(x))
 4 char ma[1005][1005];
 5 int R[1000050],C[1000050];
 6 int tot,fi,fj,n,m;
 7 bool judge()
 8 {
 9     for(int i=1;i<=n;i++)
10     {
11         for(int j=1;j<=m;j++)
12         {
13             int cur = R[i] + C[j];
14             if(ma[i][j] == ‘*‘) cur--;
15             if(tot == cur)
16             {
17                 fi = i, fj = j;
18                 return true;
19             }
20
21         }
22     }
23     return false;
24 }
25 int main()
26 {
27     while(~scanf("%d%d",&n,&m))
28     {
29         mem0(R);
30         mem0(C);
31         for(int i=1;i<=n;i++)
32             scanf("%s",ma[i]+1);//输入的一个小技巧
33         tot = 0;
34         for(int i=1;i<=n;i++)
35             for(int j=1;j<=m;j++)
36                 if(ma[i][j] == ‘*‘)
37                 {
38                     R[i] ++;
39                     C[j] ++;
40                     tot++;
41                 }
42         if(judge())
43             printf("YES\n%d %d\n",fi,fj);
44         else
45             printf("NO\n");
46     }
47     return 0;
48 }

C题 http://codeforces.com/problemset/problem/698/A

dp,小心一下 任何一种情况下都是能选择休息的。

 1 #include <cstdio>
 2 #include <map>
 3 #include <queue>
 4 #include <cstring>
 5 #include <algorithm>
 6 #include <iostream>
 7 using namespace std;
 8 #define mem0(x) memset(x,0,sizeof(x))
 9 #define mem1(x) memset(x,-1,sizeof(x))
10 typedef long long LL;
11 const int INF = 0x3f3f3f3f;
12
13
14 int a;
15 int dp[105][3];
16 int main()
17 {
18     int n;
19     scanf("%d",&n);
20     for(int i=1;i<=n;i++)
21     {
22         scanf("%d",&a);
23         if(a == 0)
24         {
25             dp[i][0] = max(max(dp[i-1][0], dp[i-1][1]), dp[i-1][2]);
26         }
27         else if(a == 1)
28         {
29             dp[i][0] = max(max(dp[i-1][0],dp[i-1][1]),dp[i-1][2]);
30             dp[i][1] = max(dp[i-1][0], dp[i-1][2]) + 1;
31         }
32         else if(a == 2)
33         {
34             dp[i][0] = max(max(dp[i-1][0],dp[i-1][1]),dp[i-1][2]);
35             dp[i][2] = max(dp[i-1][0], dp[i-1][1]) + 1;
36         }
37         else
38         {
39             dp[i][0] = max(max(dp[i-1][0],dp[i-1][1]),dp[i-1][2]);
40             dp[i][1] = max(dp[i-1][0], dp[i-1][2]) + 1;
41             dp[i][2] = max(dp[i-1][0], dp[i-1][1]) + 1;
42         }
43     }
44     int maxn = 0;
45     for(int i=0;i<3;i++)
46         maxn = max(maxn, dp[n][i]);
47     printf("%d\n",n-maxn);
48     return 0;
49 }

D题 http://codeforces.com/problemset/problem/698/B

这题挺难想的当时。先思考整个问题,无非是由若干个环和若干棵树来组成了最初的图。

如果都是树,那么很好解决,选一棵树作为主树,其他的树根直接链接到主树的根上就解决问题了,修改次数应该是根结点的总数目-1。

如果都是环,那么,把某个环的某个结点接到自己身上,形成一棵树之后,其他的环直接接上来就好了。

如果是环和树都有,那么只要把环接到主树上就好了。

 1 #include <cstdio>
 2 #include <map>
 3 #include <queue>
 4 #include <cstring>
 5 #include <algorithm>
 6 #include <iostream>
 7 using namespace std;
 8 #define mem0(x) memset(x,0,sizeof(x))
 9 #define mem1(x) memset(x,-1,sizeof(x))
10 typedef long long LL;
11 const int INF = 0x3f3f3f3f;
12
13 int a[200005];
14 int pa[200005];
15 int uf_find(int x)
16 {
17     if(x==pa[x]) return x;
18     return pa[x] = uf_find(pa[x]);
19 }
20
21 int main()
22 {
23     int n,cnt,root;
24     scanf("%d",&n);
25     //uf_init
26     for(int i=1;i<=n;i++) pa[i] = i ;
27
28     cnt = 0, root = 0;
29     for(int i=1;i<=n;i++)
30     {
31         scanf("%d",&a[i]);
32         if(i == a[i])
33         {
34             cnt++,root = i;
35         }
36         else
37         {
38             int fx = uf_find(i);
39             int fy = uf_find(a[i]);
40             if(fx == fy)   a[i] = i,cnt++;//成环
41             else           pa[fx] = fy;
42         }
43     }
44     if(root == 0)
45     {
46         for(int i=1;i<=n;i++)
47         {
48             if(i == pa[i])
49             {
50                 root = i;
51                 break;
52             }
53         }
54         cnt++;
55     }
56     printf("%d\n",cnt-1);
57     for(int i=1;i<=n;i++)
58     {
59         if(i == a[i]) a[i] = root;//根只能有一个
60         printf("%d%c",a[i],i==n?‘\n‘:‘ ‘);
61     }
62     return 0;
63 }
时间: 2024-10-10 10:01:01

codeforces #363(div.2)的相关文章

Codeforces #258 Div.2 E Devu and Flowers

大致题意: 从n个盒子里面取出s多花,每个盒子里面的花都相同,并且每个盒子里面花的多数为f[i],求取法总数. 解题思路: 我们知道如果n个盒子里面花的数量无限,那么取法总数为:C(s+n-1, n-1) = C(s+n-1, s). 可以将问题抽象成:x1+x2+...+xn = s, 其中0<=xi <= f[i],求满足条件的解的个数. 两种方法可以解决这个问题: 方法一:这个问题的解可以等价于:mul = (1+x+x^2+...+x^f[1])*(1+x+x^2+...+x^f[2]

Codeforces #259 Div.2

A. Little Pony and Crystal Mine 模拟题. 用矩阵直接构造或者直接根据关系输出 B. Little Pony and Sort by Shift 模拟题. 通过提供的操作得到的序列只能是两段递增或者整个序列递增. 那么可以求得第一段递增序列长度为0-p 如果整个序列是递增,即 p= n-1 那么操作次数就是0. 否则,假设是两段递增,把原始的序列恢复出来,设当前序列是AB,那么A就是0-p BA = (A'B')', '表示对序列进行翻转, 如果BA是有序的,那么需

Codeforces #250 (Div. 2) C.The Child and Toy

之前一直想着建图...遍历 可是推例子都不正确 后来看数据好像看出了点规律 就抱着试一试的心态水了一下 就....过了..... 后来想想我的思路还是对的 先抽象当前仅仅有两个点相连 想要拆分耗费最小,肯定拆相应权值较小的 在这个基础上考虑问题就能够了 代码例如以下: #include <cstdio> #include <iostream> #include <algorithm> #define MAXN 10010 #define ll long long usi

Codeforces #256 Div.2

B. Suffix Structure 1. 先判断s去掉一些元素是否能构成t,如果可以就是automaton 判断的方法也很简单,two pointer,相同元素同时++,不相同s的指针++,如果t能全找到,那么s能够去掉元素构成t. bool f(string s, string t) { int i = 0, j = 0; while (i < s.size() && j < t.size()) { if (s[i] == t[j]) { i++; j++; } else

Codeforces Round #363 (Div. 2)

A. Launch of Collider 根据字符左移或右移,输出第一次碰撞的位置,不然输出-1 1 #include <cstdio> 2 #include <iostream> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 #define LL long long 7 char ch[200005]; 8 LL a[200005],ans; 9 int n; 1

CodeForces 698A - Vacations (Codeforces Round #363 (Div. 2))

要么去体育馆,要么去比赛,要么闲在家里 给出每一天体育馆和比赛的有无情况,要求连续两天不能去同一个地方 问最少闲几天 DP方程很容易看出 dp(第i天能去的地方) = min(dp(第i-1天的三种情况)) : dp(第i天呆在家里) = min(dp(第i-1天的三种情况))+1: 1 #include <cstdio> 2 #include <iostream> 3 using namespace std; 4 #define inf 0x3f3f3f3f 5 int a[10

Codeforces Round #363 Div.2[11110]

好久没做手生了,不然前四道都是能A的,当然,正常发挥也是菜. A:Launch of Collider 题意:20万个点排在一条直线上,其坐标均为偶数.从某一时刻开始向左或向右运动,速度为每秒1个单位长度.输入给出每个点的坐标及其移动的方向,求发生第一次碰撞的时间,若不会碰撞,则输出-1 最先发生碰撞的是一定是初始时相邻的两个点,因此只需对每个点循环一边,判断其是否会与下一个点碰撞,并求出其时间即可. #include<stdio.h> #include<stdlib.h> int

Codeforces Round #363 (Div. 1) C. LRU

题意: n个数,长度为k的缓存,每次询问,每个数以pi的概率被选,如果不在缓存区则加入,如果缓存区满了,则第一个进缓存的出来,问10^100次询问以后每个数在缓存的概率 思路: 状压DP,看了hzwer的代码 f[x]表示当前状态为x的概率 枚举不在缓存区的数:f[t]+=f[x]*(p[i]/tot);  t=x|(1<<(i-1)); tot是当前状态情况下,不在缓存区的所有概率 如果缓存区数大于k,则当前状态概率为0 1 // #pragma comment(linker, "

Codeforces Round #363 (Div. 2)A-D

699A 题意:在一根数轴上有n个东西以相同的速率1m/s在运动,给出他们的坐标以及运动方向,问最快发生的碰撞在什么时候 思路:遍历一遍坐标,看那两个相邻的可能相撞,更新ans #include<cstdio> int n,num[200100]; char s[200100]; int main() { scanf("%d",&n); scanf("%s",s+1); for(int i=1;i<=n;i++) scanf("%