A
http://codeforces.com/contest/699/problem/A
有点智障的读了好久的题。。还思考了一下会不会出现隔着相遇的,但是是不可能的,只能是相邻
There will be a launch of a new, powerful and unusual collider very soon, which located along a straight line. n particles will be launched inside it. All of them are located in a straight line and there can not be two or more particles located in the same point. The coordinates of the particles coincide with the distance in meters from the center of the collider, xi is the coordinate of the i-th particle and its position in the collider at the same time. All coordinates of particle positions are even integers……
#include <iostream>
#include<cstring>
#include <climits>
#include <cstdio>
using namespace std;
char s[200010];
int a[200010];
int main()
{
int n;
cin >> n;
scanf("%s",s);
cin >> a[0];
int ans = INT_MAX;
for (int i = 1 ; i < n; i++)
{
cin >>a[i];
if(s[i]=='L'&& s[i-1] == 'R' )
ans = min(ans,(a[i-1]+(a[i]-a[i-1])/2)-a[i-1]);
}
if(ans != INT_MAX)
cout << ans <<endl;
else
cout << -1 <<endl;
return 0;
}
B
http://codeforces.com/contest/699/problem/B
You are given a description of a depot. It is a rectangular checkered field of n × m size. Each cell in a field can be empty (“.”) or it can be occupied by a wall (“*”).
You have one bomb. If you lay the bomb at the cell (x, y), then after triggering it will wipe out all walls in the row x and all walls in the column y.
只有一个炸弹,要把所有*都炸掉,一个炸弹能炸掉一行的一列的,
比赛的时候脑子短路,直接暴力每个位置之后 暴力剩下的行列还有没有星号。。。。n^4不超时就怪了=。=然后想到,还是暴力枚举每个位置,用num记录所有的*,如果这一行加这一列的加起来正好是总数num,那就说明是可以的,如果所有的都尝试都不可以就是no咯,但是部枚举每个位置上放炸弹,而是直接if else 不仅很麻烦,而且会被cha。。。我认识的一半人都挂了=。=
#include<iostream>
#include <stdio.h>
#include <math.h>
#include<string.h>
#include<algorithm>
#define MAXN 1000+10
using namespace std;
char s[MAXN][MAXN], x[MAXN], y[MAXN], num;
int main()
{
int m, n;
cin >> m >> n;
for(int i=1; i<=m; i++)
for(int j=1; j<=n; j++)
cin >> s[i][j];
for(int i=1; i<=m; i++)
for(int j=1; j<=n; j++)
if(s[i][j]=='*')
{
x[i]++;
y[j]++;
num++;
}
for(int i=1; i<=m; i++)
for(int j=1; j<=n; j++)
if(x[i]+y[j]==num && s[i][j]!='*' || s[i][j]=='*' && x[i]+y[j]-1==num)
{
printf("YES\n");
printf("%d %d\n", i, j);
return 0;
}
printf("NO\n");
return 0;
}
c
http://codeforces.com/contest/699/problem/C
Vasya has n days of vacations! So he decided to improve his IT skills and do sport. Vasya knows the following information about each of this n days: whether that gym opened and whether a contest was carried out in the Internet on that day. For the i-th day there are four options:
on this day the gym is closed and the contest is not carried out;
on this day the gym is closed and the contest is carried out;
on this day the gym is open and the contest is not carried out;
on this day the gym is open and the contest is carried out.
简单线性dp,这一天可以休息,可以打比赛,可以运动,于是写dp【i][j]表示到了第i天,如果休息的话总共休息了多少天,如果打比赛休息了多少天,如果运动休息了多少天
dp【i】【0】=min(dp【i-1】【1】,dp【i-1】【2】,dp【i-1】【0】)+1;
dp【i】【1】=min(dp【i-1】【0】,dp【i-1】【2】);
dp【i】【2】=min(dp【i-1】【0】,dp【i-1】【1】);
注意如果这一天就是干不了一件事,比如运动馆不开放你就运动不了,那么dp这个活动给最大值,原因就是说好了方程式就是这天干这几件,然而你干不了,那就只能给最大值,表示这个状态是不存在的。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<list>
#include<vector>
#define inf 0x3f3f3f3f
using namespace std;
int num[110];
int dp[110][4];
int main()
{
int n;cin>>n;
for(int i=1;i<=n;++i){
scanf("%d",&num[i]);
}
for(int i=1;i<=n;++i){
for(int j=0;j<3;++j){
dp[i][0]=min(dp[i-1][0],min(dp[i-1][1],dp[i-1][2]))+1;
if(num[i]==1||num[i]==3){
dp[i][1]=min(dp[i-1][0],dp[i-1][2]);
}
else {
dp[i][1]=inf;
}
if(num[i]==2||num[i]==3){
dp[i][2]=min(dp[i-1][0],dp[i-1][1]);
}
else {
dp[i][2]=inf;
}
}
}
printf("%d\n",min(dp[n][0],min(dp[n][1],dp[n][2])));
return 0;
}
d
http://codeforces.com/contest/699/problem/D
A tree is an undirected connected graph without cycles.
Let’s consider a rooted undirected tree with n vertices, numbered 1 through n. There are many ways to represent such a tree. One way is to create an array with n integers p1, p2, …, pn, where pi denotes a parent of vertex i (here, for convenience a root is considered its own parent).
先用并查集判断该图是否有环,如果没环,那就是树。
有环的话,先判断这些环中是否有一个单一节点树,然后将其他环全部加到这个树上。
如果没有这样一棵树,那么就任意将某一条环拆成一个树,再将其他环都拆掉加到这棵树中。
#include <cstdio>
#include <iostream>
#include <cstring>
int a[200010],fa[200010],ans[200010];
int t;
using namespace std;
int findroot(int x)
{
if(fa[x] == x)
return x;
return fa[x] = findroot(fa[x]);
}
int main()
{
int n;
cin >> n;
int cnt = 0;
for (int i = 1 ; i <= n ;i++)
fa[i] = i;
for (int i = 1; i <= n ;i++)
{
cin >> a[i];
int fx = findroot(i),fy = findroot(a[i]);
if(fx == fy) //出现环了
{
ans[cnt++] = i; //记录下当前出现环的节点
if(a[i] == i) //出现只有一个节点的树了
t = fx;
//t是最后那个树的根=。=,只有一个节点的这个比较好,自己不用改
}
else
fa[i] = a[i];
}
if(t==0) //没有咱们要的那种独立节点树
{
for (int i = 1 ; i <= n ;i++)
{
int fx = findroot(i),fy = findroot(a[i]);
if(fx == fy)
t = fy; //如果是有环的那种,就随便找一个跟(这里循环走到最后了,就是最后一个出现环的那一个节点)
}
}
int cn = 0;//如果本来的顺序可以了,这里cnt是0 不走这个循环,其他情况下,出现环的地方都改在刚才我们找到的t下面
for (int i = 0 ; i<cnt ;i++)
{
if(a[ans[i]] != t)
{
cn++;
a[ans[i]] = t;
}
}
cout <<cn <<endl;
for (int i = 1 ; i <= n ;i++)
printf("%d%c",a[i],(i == n)?'\n':' ');
}