您的位置:首页 > 其它

Educational Codeforces Round 40 (Rated for Div. 2)

2018-03-23 21:50 615 查看
A. Diagonal Walkingtime limit per test1 secondmemory limit per test256 megabytesinputstandard inputoutputstandard outputMikhail walks on a 2D plane. He can go either up or right. You are given a sequence of Mikhail's moves. He thinks that this sequence is too long and he wants to make it as short as possible.In the given sequence moving up is described by character U and moving right is described by character R. Mikhail can replace any pair of consecutive moves RU or UR with a diagonal move (described as character D). After that, he can go on and do some other replacements, until there is no pair of consecutive moves RU or UR left.Your problem is to print the minimum possible length of the sequence of moves after the replacements.InputThe first line of the input contains one integer n (1 ≤ n ≤ 100) — the length of the sequence. The second line contains the sequence consisting of n characters U and R.OutputPrint the minimum possible length of the sequence of moves after all replacements are done.ExamplesinputCopy
5
RUURU
output
3
inputCopy
17
UUURRRRRUUURURUUU
output
13
NoteIn the first test the shortened sequence of moves may be DUD (its length is 3).In the second test the shortened sequence of moves can be UUDRRRDUDDUUU (its length is 13).


#include <cstdio>
#include <iostream>
#include <string.h>
#include <string>
#include <map>
#include <queue>
#include <deque>
#include <vector>
#include <set>
#include <algorithm>
#include <math.h>
#include <cmath>
#include <stack>
#include <iomanip>
#define mem0(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,0x3f,sizeof(a))
using namespace std;
typedef long long ll;
typedef long double ld;
typedef double db;
const int maxn=100005,inf=0x3f3f3f3f;
const ll llinf=0x3f3f3f3f3f3f3f3f;
const ld pi=acos(-1.0L);
char s[maxn];

int main() {
int n,i,x,y;
scanf("%d",&n);
scanf("%s",s+1);
int ans=n;
for (i=1;i<=n;i++) {
if (i!=n)
if (s[i]!=s[i+1]) ans--,i++;
}
cout << ans;
return 0;
}B. String Typingtime limit per test1 secondmemory limit per test256 megabytesinputstandard inputoutputstandard outputYou are given a string s consisting of n lowercase Latin letters. You have to type this string using your keyboard.Initially, you have an empty string. Until you type the whole string, you may perform the following operation:
add a character to the end of the string.
Besides, at most once you may perform one additional operation: copy the string and append it to itself.For example, if you have to type string abcabca, you can type it in 7 operations if you type all the characters one by one. However, you can type it in 5 operations if you type the string abc first and then copy it and type the last character.If you have to type string aaaaaaaaa, the best option is to type 4 characters one by one, then copy the string, and then type the remaining character.Print the minimum number of operations you need to type the given string.InputThe first line of the input containing only one integer number n (1 ≤ n ≤ 100) — the length of the string you have to type. The second line containing the string s consisting of n lowercase Latin letters.OutputPrint one integer number — the minimum number of operations you need to type the given string.ExamplesinputCopy
7
abcabca
output
5
inputCopy
8
abcdefgh
output
8
NoteThe first test described in the problem statement.In the second test you can only type all the characters one by one.

同样水

#include <cstdio>
#include <iostream>
#include <string.h>
#include <string>
#include <map>
#include <queue>
#include <deque>
#include <vector>
#include <set>
#include <algorithm>
#include <math.h>
#include <cmath>
#include <stack>
#include <iomanip>
#define mem0(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,0x3f,sizeof(a))
using namespace std;
typedef long long ll;
typedef long double ld;
typedef double db;
const int maxn=1005,inf=0x3f3f3f3f;
const ll llinf=0x3f3f3f3f3f3f3f3f;
const ld pi=acos(-1.0L);
char s[maxn];

int main() {
int n,i,j,ans=-1;
scanf("%d",&n);
scanf("%s",s+1);
for (i=1;i<=n/2;i++) {
int flag=1;
for (j=1;j<=i;j++) {
if (s[j]!=s[j+i]) flag=0;
}
if (flag) ans=i;
}
if (ans==-1) ans=n; else ans=min(n-ans+1,n);
cout << ans;
return 0;
}C. Matrix Walktime limit per test1 secondmemory limit per test256 megabytesinputstandard inputoutputstandard outputThere is a matrix A of size x × y filled with integers. For every 



 Ai, j = y(i - 1) + j. Obviously, every integer from [1..xy] occurs exactly once in this matrix.You have traversed some path in this matrix. Your path can be described as a sequence of visited cells a1, a2, ..., an denoting that you started in the cell containing the number a1, then moved to the cell with the number a2, and so on.From the cell located in i-th line and j-th column (we denote this cell as (i, j)) you can move into one of the following cells:
(i + 1, j) — only if i < x;
(i, j + 1) — only if j < y;
(i - 1, j) — only if i > 1;
(i, j - 1) — only if j > 1.
Notice that making a move requires you to go to an adjacent cell. It is not allowed to stay in the same cell. You don't know x and y exactly, but you have to find any possible values for these numbers such that you could start in the cell containing the integer a1, then move to the cell containing a2 (in one step), then move to the cell containing a3 (also in one step) and so on. Can you choose x and y so that they don't contradict with your sequence of moves?InputThe first line contains one integer number n (1 ≤ n ≤ 200000) — the number of cells you visited on your path (if some cell is visited twice, then it's listed twice).The second line contains n integers a1, a2, ..., an (1 ≤ ai ≤ 109) — the integers in the cells on your path.OutputIf all possible values of x and y such that 1 ≤ x, y ≤ 109 contradict with the information about your path, print NO.Otherwise, print YES in the first line, and in the second line print the values x and y such that your path was possible with such number of lines and columns in the matrix. Remember that they must be positive integers not exceeding 109.ExamplesinputCopy
81 2 3 6 9 8 5 2
output
YES
3 3
inputCopy
61 2 1 2 5 3
output
NO
inputCopy
2
1 10
output
YES
4 9
NoteThe matrix and the path on it in the first test looks like this:

Also there exist multiple correct answers for both the first and the third examples.

注意到只能上下或左右走,而左右走时,绝对值差必为1;上下走时,绝对值差可能不为1,但一定相等,且为一行的元素数。
如此,只要判断序列中所有相邻数的绝对值差是不是只有两种可能。
一种特殊的情况:从一行末尾走到下一行开头是不合法的。这种情况需要特判。
另一组特别容易挂的数据:
31 2 4

#include <cstdio>
#include <iostream>
#include <string.h>
#include <string>
#include <map>
#include <queue>
#include <deque>
#include <vector>
#include <set>
#include <algorithm>
#include <math.h>
#include <cmath>
#include <stack>
#include <iomanip>
#define mem0(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,0x3f,sizeof(a))
using namespace std;
typedef long long ll;
typedef long double ld;
typedef double db;
const int maxn=200005,inf=0x3f3f3f3f;
const ll llinf=0x3f3f3f3f3f3f3f3f;
const ld pi=acos(-1.0L);
int a[maxn];

int main() {
int n,i,j;
scanf("%d",&n);
j=-1;
for (i=1;i<=n;i++) {
scanf("%d",&a[i]);
if (i!=1) j=max(j,abs(a[i]-a[i-1]));
if (a[i]==a[i-1]&&i!=1) {
printf("NO\n");
return 0;
}
}
if (j==1) {
int ans=-1;
for (i=1;i<=n;i++) ans=max(ans,a[i]);
printf("YES\n%d 1\n",ans);return 0;
}
if (n==1) {
printf("YES\n%d 1\n",a[1]);return 0;
}
for (i=2;i<=n;i++) {
if (abs(a[i]-a[i-1])!=j&&abs(a[i]-a[i-1])!=1) {
printf("NO\n");
return 0;
}
}
for (i=2;i<=n;i++) {
if (abs(a[i]-a[i-1])==1) { //判断是否从一行结尾走到下一行开头
if (a[i]%j==0&&a[i-1]%j==1&&a[i]/j==a[i-1]/j) {
printf("NO\n");
return 0;
}
if (a[i]%j==1&&a[i-1]%j==0&&a[i]/j==a[i-1]/j) {
printf("NO\n");
return 0;
}
}
}
printf("YES\n1000000000 %d\n",j);
return 0;
}D. Fight Against Traffictime limit per test1 secondmemory limit per test256 megabytesinputstandard inputoutputstandard outputLittle town Nsk consists of n junctions connected by m bidirectional roads. Each road connects two distinct junctions and no two roads connect the same pair of junctions. It is possible to get from any junction to any other junction by these roads. The distance between two junctions is equal to the minimum possible number of roads on a path between them.In order to improve the transportation system, the city council asks mayor to build one new road. The problem is that the mayor has just bought a wonderful new car and he really enjoys a ride from his home, located near junction s to work located near junction t. Thus, he wants to build a new road in such a way that the distance between these two junctions won't decrease.You are assigned a task to compute the number of pairs of junctions that are not connected by the road, such that if the new road between these two junctions is built the distance between s and t won't decrease.
InputThe firt line of the input contains integers n, m, s and t (2 ≤ n ≤ 1000, 1 ≤ m ≤ 1000, 1 ≤ s, t ≤ n, s ≠ t) — the number of junctions and the number of roads in Nsk, as well as the indices of junctions where mayors home and work are located respectively. The i-th of the following m lines contains two integers uiand vi (1 ≤ ui, vi ≤ n, ui ≠ vi), meaning that this road connects junctions ui and vi directly. It is guaranteed that there is a path between any two junctions and no two roads connect the same pair of junctions.OutputPrint one integer — the number of pairs of junctions not connected by a direct road, such that building a road between these two junctions won't decrease the distance between junctions s and t.ExamplesinputCopy
5 4 1 51 2
2 33 4
4 5
output
0
inputCopy
5 4 3 51 2
2 33 4
4 5
output
5
inputCopy
5 6 1 51 2
1 31 4
4 53 52 5
output
3


预处理所有点到起点和终点的距离,再O(n^2)枚举所有情况。
预处理可以直接bfs,也可以使用某种最短路算法。

#include <cstdio>
#include <iostream>
#include <string.h>
#include <string>
#include <map>
#include <queue>
#include <deque>
#include <vector>
#include <set>
#include <algorithm>
#include <math.h>
#include <cmath>
#include <stack>
#include <iomanip>
#define mem0(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,0x3f,sizeof(a))
using namespace std;
typedef long long ll;
typedef long double ld;
typedef double db;
const int maxn=1005,inf=0x3f3f3f3f;
const ll llinf=0x3f3f3f3f3f3f3f3f;
const ld pi=acos(-1.0L);
int dist[maxn],head[maxn],dis[maxn];
bool inque[maxn],f[maxn][maxn];
int num=0;
vector<int> v[maxn];

struct Edge {
int from,to,pre,dist;
};
Edge edge[maxn*2];

void addedge(int from,int to,int dist) {
edge[num]=(Edge){from,to,head[from],dist};
head[from]=num++;
edge[num]=(Edge){to,from,head[to],dist};
head[to]=num++;
}

void spfa(int s,int des){
int i;
memset(inque,0,sizeof(inque));
memset(dist,0x3f,sizeof(dist));
inque[s]=1;
queue<int> q;
q.push(s);
dist[s]=0;
while (!q.empty()) {
int now=q.front();
q.pop();
inque[now]=0;
for (i=head[now];i!=-1;i=edge[i].pre) {
int to=edge[i].to;
if (dist[edge[i].from]+edge[i].dist<dist[to]) {
q.push(to);
dist[to]=dist[edge[i].from]+edge[i].dist;
}
}
}
}

void spf(int s,int des){
int i;
memset(inque,0,sizeof(inque));
memset(dis,0x3f,sizeof(dis));
inque[s]=1;
queue<int> q;
q.push(s);
dis[s]=0;
while (!q.empty()) {
int now=q.front();
q.pop();
inque[now]=0;
for (i=head[now];i!=-1;i=edge[i].pre) {
int to=edge[i].to;
if (dis[edge[i].from]+edge[i].dist<dis[to]) {
q.push(to);
dis[to]=dis[edge[i].from]+edge[i].dist;
}
}
}
}

int main() {
int n,m,i,j,x,y,s,t;
num=0;
memset(head,-1,sizeof(head));
mem0(f);
scanf("%d%d%d%d",&n,&m,&s,&t);
for (i=1;i<=m;i++) {
scanf("%d%d",&x,&y);
addedge(x,y,1);
f[x][y]=f[y][x]=1;
}
spfa(s,t);
spf(t,s);
int ans=0;
for (i=1;i<=n;i++) {
for (j=i+1;j<=n;j++) {
if (f[i][j]) continue;
if (1+dist[i]+dis[j]>=dist[t]&&1+dist[j]+dis[i]>=dist[t]) ans++;
}
}
printf("%d\n",ans);
return 0;
}E. Water Tapstime limit per test2 secondsmemory limit per test256 megabytesinputstandard inputoutputstandard outputConsider a system of n water taps all pouring water into the same container. The i-th water tap can be set to deliver any amount of water from 0 to ai ml per second (this amount may be a real number). The water delivered by i-th tap has temperature ti.If for every 

 you set i-th tap to deliver exactly xi ml of water per second, then the resulting temperature of water will be 

 (if 

, then to avoid division by zero we state that the resulting water temperature is 0).You have to set all the water taps in such a way that the resulting temperature is exactly T. What is the maximum amount of water you may get per second if its temperature has to be T?
InputThe first line contains two integers n and T (1 ≤ n ≤ 200000, 1 ≤ T ≤ 106) — the number of water taps and the desired temperature of water, respectively.The second line contains n integers a1, a2, ..., an (1 ≤ ai ≤ 106) where ai is the maximum amount of water i-th tap can deliver per second.The third line contains n integers t1, t2, ..., tn (1 ≤ ti ≤ 106) — the temperature of water each tap delivers.OutputPrint the maximum possible amount of water with temperature exactly T you can get per second (if it is impossible to obtain water with such temperature, then the answer is considered to be 0).Your answer is considered correct if its absolute or relative error doesn't exceed 10 - 6.ExamplesinputCopy
2 1003 1050 150
output
6.000000000000000
inputCopy
3 9
5 5 306 6 10
output
40.000000000000000
inputCopy
2 12
1 310 15
output
1.666666666666667


一个结论:我们总是能够用完比T温度高的所有龙头,或比T温度低的所有龙头。

证明:假设我们把这两半的$$\sum x_{i}(t_{i}-T)$$ 相比较,一定是一正一负。那么,绝对值少的那一部分总会被耗光,因为另一部分总能和它们中和,使得总温度为T.那么,在其中一半用光的情况下,另外一半当中一定是尽量选温度离T近的水更优,因为这时$$\sum x_{i}(t_{i}-T)$$定了,$$(t_{i}-T)$$越小,$$x_{i}$$总和就越大。

所以只要假设这两部分其中一部分用光,另一部分贪心,比较一下两种情况哪种最优就好了。
代码没写完,待补。

F. Runner's Problemtime limit per test4 secondsmemory limit per test256 megabytesinputstandard inputoutputstandard outputYou are running through a rectangular field. This field can be represented as a matrix with 3 rows and mcolumns. (i, j) denotes a cell belonging to i-th row and j-th column.You start in (2, 1) and have to end your path in (2, m). From the cell (i, j) you may advance to:(i - 1, j + 1) — only if i > 1,
(i, j + 1), or
(i + 1, j + 1) — only if i < 3.
However, there are n obstacles blocking your path. k-th obstacle is denoted by three integers ak, lk and rk, and it forbids entering any cell (ak, j) such that lk ≤ j ≤ rk.You have to calculate the number of different paths from (2, 1) to (2, m), and print it modulo 109 + 7.InputThe first line contains two integers n and m (1 ≤ n ≤ 104, 3 ≤ m ≤ 1018) — the number of obstacles and the number of columns in the matrix, respectively.Then n lines follow, each containing three integers ak, lk and rk (1 ≤ ak ≤ 3, 2 ≤ lk ≤ rk ≤ m - 1) denoting an obstacle blocking every cell (ak, j) such that lk ≤ j ≤ rk. Some cells may be blocked by multiple obstacles.OutputPrint the number of different paths from (2, 1) to (2, m), taken modulo 109 + 7. If it is impossible to get from (2, 1) to (2, m), then the number of paths is 0.ExampleinputCopy
2 51 3 4
2 2 3
output
2

DP+矩阵快速幂。
把一个列的每格的方法数定义为一个1*3的列向量,每一列都可以由前一列DP,那么可以把整个地图分成很多段,每段用一个递推矩阵DP。有多少列,就左乘多少次这个矩阵。
多个障碍的话,根据障碍出现和消失的位置排序,依次处理。
要注意的是,障碍可以重叠。

#include <cstdio>
#include <iostream>
#include <string.h>
#include <string>
#include <map>
#include <queue>
#include <deque>
#include <vector>
#include <set>
#include <algorithm>
#include <math.h>
#include <cmath>
#include <stack>
#include <iomanip>
#define mem0(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,0x3f,sizeof(a))
using namespace std;
typedef long long ll;
typedef long double ld;
typedef double db;
const int maxn=10005,inf=0x3f3f3f3f,size=3;
const ll llinf=0x3f3f3f3f3f3f3f3f,mod=1e9+7;
const ld pi=acos(-1.0L);
ll ac[3];

struct block{
ll a,p;
bool f;
};
block b[maxn*2];

bool cmp(block a,block b) {
return a.p<b.p || (a.p==b.p&&a.f<b.f);
}

struct Matrix {
ll a[size][size];
};
Matrix ans,p,base;

Matrix operator*(const Matrix &x,const Matrix &y) {
int i,j,k;
Matrix ans;
for (i=0;i<size;i++) {
for (j=0;j<size;j++) {
ans.a[i][j]=0;
for (k=0;k<size;k++) {
ans.a[i][j]+=x.a[i][k]*y.a[k][j];
ans.a[i][j]%=mod;
}
}
}
return ans;
}

Matrix fastpower(Matrix base,ll index) {
Matrix ans,now;
int i,j;
for (i=0;i<size;i++) {
for (j=0;j<size;j++) {
if (i==j) ans.a[i][j]=1; else ans.a[i][j]=0;
}
}
now=base;
ll k=index;
while (k) {
if (k%2) ans=ans*now;
now=now*now;
k/=2;
}
return ans;
}

void minu(ll i) {
for (int j=0;j<size;j++)
p.a[b[i].a][j]=0;
}

void add(ll i) {
for (int j=0;j<size;j++)
p.a[b[i].a][j]=base.a[b[i].a][j];
}

int main() {
ll n,m,i,j,x,y,z;
scanf("%I64d%I64d",&n,&m);
for (i=1;i<=n;i++) {
scanf("%I64d%I64d%I64d",&x,&y,&z);
b[i*2-1].a=x-1;b[i*2-1].p=y;b[i*2-1].f=1;
b[i*2].a=x-1;b[i*2].p=z+1;b[i*2].f=0;
}
ac[0]=ac[1]=ac[2]=0;
sort(b+1,b+n*2+1,cmp);
for (i=0;i<size;i++)
for (j=0;j<size;j++) {
if (i==2&&j==0) p.a[i][j]=0; else
if (i==0&&j==2) p.a[i][j]=0; else p.a[i][j]=1;
base.a[i][j]=p.a[i][j];
}
for (i=0;i<size;i++)
for (j=0;j<size;j++)
if (i!=j) ans.a[i][j]=0; else ans.a[i][j]=1;
ans=fastpower(p,b[1].p-2)*ans;
i=0;
while (i<n*2) {
i++;
if (b[i].f==0) ac[b[i].a]--; else ac[b[i].a]++;
if (ac[b[i].a]==0) add(i);
if (ac[b[i].a]==1&&b[i].f==1) minu(i);
while (b[i+1].p==b[i].p&&i<n*2) {
i++;
if (b[i].f==0) ac[b[i].a]--; else ac[b[i].a]++;
if (ac[b[i].a]==0) add(i);
if (ac[b[i].a]==1&&b[i].f==1) minu(i);
}
if (i==n*2) break;
ans=fastpower(p,b[i+1].p-b[i].p)*ans;
}
ans=fastpower(p,m-b[n*2].p+1)*ans;
ll sum=ans.a[1][1];
printf("%I64d\n",sum);
return 0;
}G. Castle Defensetime limit per test1.5 secondsmemory limit per test256 megabytesinputstandard inputoutputstandard outputToday you are going to lead a group of elven archers to defend the castle that is attacked by an army of angry orcs. Three sides of the castle are protected by impassable mountains and the remaining side is occupied by a long wall that is split into n sections. At this moment there are exactly ai archers located at the i-th section of this wall. You know that archer who stands at section i can shoot orcs that attack section located at distance not exceeding r, that is all such sections j that |i - j| ≤ r. In particular, r = 0 means that archers are only capable of shooting at orcs who attack section i.Denote as defense level of section i the total number of archers who can shoot at the orcs attacking this section. Reliability of the defense plan is the minimum value of defense level of individual wall section.There is a little time left till the attack so you can't redistribute archers that are already located at the wall. However, there is a reserve of k archers that you can distribute among wall sections in arbitrary way. You would like to achieve maximum possible reliability of the defence plan.
InputThe first line of the input contains three integers n, r and k (1 ≤ n ≤ 500 000, 0 ≤ r ≤ n, 0 ≤ k ≤ 1018) — the number of sections of the wall, the maximum distance to other section archers can still shoot and the number of archers yet to be distributed along the wall. The second line contains n integers a1, a2, ..., an(0 ≤ ai ≤ 109) — the current number of archers at each section.OutputPrint one integer — the maximum possible value of defense plan reliability, i.e. the maximum possible value of minimum defense level if we distribute k additional archers optimally.ExamplesinputCopy
5 0 6
5 4 3 4 9
output
5
inputCopy
4 2 01 2 3 4
output
6
inputCopy
5 1 1
2 1 2 1 2
output
3


二分答案。
从左到右扫描,找到一个人数不符要求的地方,就补上少的人数。
很自然的,这时把这些少的人尽量放在右边最优,覆盖的范围最广。
利用前缀和完成上述check操作。
最后看一下补的人有没有k个就好了。

#include <cstdio>
#include <iostream>
#include <string.h>
#include <string>
#include <map>
#include <queue>
#include <deque>
#include <vector>
#include <set>
#include <algorithm>
#include <math.h>
#include <cmath>
#include <stack>
#include <iomanip>
#define mem0(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,0x3f,sizeof(a))
using namespace std;
typedef long long ll;
typedef long double ld;
typedef double db;
const int maxn=500005,inf=0x3f3f3f3f;
const ll llinf=0x3f3f3f3f3f3f3f3f;
const ld pi=acos(-1.0L);
ll sum[maxn],a[maxn],t[maxn];

bool check(ll mid,ll q,ll p,ll n) {
ll i,j,k=p,ssum=0;
mem0(t);
for (i=1;i<=n;i++) {
ssum+=sum[i]+t[i];
if (ssum>=mid) continue;
ll com=mid-ssum;
k-=com;
if (k<0) return false;
ssum+=com;
t[min(n+1,i+q*2+1)]-=com;
}
return true;
}

int main() {
ll n,k,r,i,j,l,mid,q;
scanf("%I64d%I64d%I64d",&n,&q,&k);
mem0(sum);
for (i=1;i<=n;i++) {
scanf("%I64d",&a[i]);
sum[max(1ll,i-q)]+=a[i];
sum[min(n+1,i+q+1)]-=a[i];
}
l=1;r=2e18;ll ans=0;
while (l<=r) {
mid=(l+r)/2;
if (check(mid,q,k,n)) ans=mid,l=mid+1; else r=mid-1;
}
printf("%I64d\n",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐