Nenu复健训练#2

Water the Garden #Codeforces 920A

It is winter now, and Max decided it's about time he watered the garden.

The garden can be represented as n consecutive garden beds, numbered from 1 to n. k beds contain water taps (i-th tap is located in the bed xi), which, if turned on, start delivering water to neighboring beds. If the tap on the bed xi is turned on, then after one second has passed, the bed xi will be watered; after two seconds have passed, the beds from the segment [xi - 1, xi + 1] will be watered (if they exist); after j seconds have passed (j is an integer number), the beds from the segment [xi - (j - 1), xi + (j - 1)] will be watered (if they exist). Nothing changes during the seconds, so, for example, we can't say that the segment [xi - 2.5, xi + 2.5] will be watered after 2.5 seconds have passed; only the segment [xi - 2, xi + 2] will be watered at that moment.

 

The garden from test 1. White colour denotes a garden bed without a tap, red colour — a garden bed with a tap.

The garden from test 1 after 2 seconds have passed after turning on the tap. White colour denotes an unwatered garden bed, blue colour — a watered bed.

Max wants to turn on all the water taps at the same moment, and now he wonders, what is the minimum number of seconds that have to pass after he turns on some taps until the whole garden is watered. Help him to find the answer!

  • Input:

The first line contains one integer t — the number of test cases to solve (1 ≤ t ≤ 200).

Then t test cases follow. The first line of each test case contains two integers n and k (1 ≤ n ≤ 200, 1 ≤ k ≤ n) — the number of garden beds and water taps, respectively.

Next line contains k integers xi (1 ≤ xi ≤ n) — the location of i-th water tap. It is guaranteed that for each condition xi - 1 < xi holds.

It is guaranteed that the sum of n over all test cases doesn't exceed 200.

Note that in hacks you have to set t = 1.

  • Output

For each test case print one integer — the minimum number of seconds that have to pass after Max turns on some of the water taps until the whole garden is watered.

Sample

Input
3
5 1
3
3 3
1 2 3
4 1
1
Output
3
1
4

Note 就不了了之了qwq

思路一开始是数组模拟,后来发现用数学可以解决问题tmd

  • 数组模拟的版本(好菜啊这个写的)
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#define res register int
#define dd double
#define ll long long
using namespace std;
const int maxn=1e3+12;
int k[maxn];bool vis[maxn];
int main(){ 
    int n,T,sum;
    scanf("%d",&T);
    while(T--){
        memset(vis,false,sizeof(vis));
	scanf("%d%d",&n,&sum);
	for(res i=1;i<=sum;i++) scanf("%d",&k[i]);	
	int cnt=n;int cur=0;
	while(cnt!=0){
	    for(res i=1;i<=sum;i++){
	        int a=k[i]-cur;
	    	int b=k[i]+cur;
	    	if(vis[a]==false&&a>0&&a<=n){
                    cnt--;vis[a]=true;
		}
		if(vis[b]==false&&b>0&&b<=n){
		    cnt--;vis[b]=true;
		}
	    }
	    cur++;	
	}
	printf("%d\n",cur);
	}
    return 0;
}
  • 然后数学的(考虑水龙头之间,例如距离为1,则时间就是1,距离为2时间为1距离为3时间就是2,规律很明了:距离对2取余,有余数则距离/2+1,否则距离/2。枚举水龙头之间的距离即可。
#include<iostream>
#include<cstdio>
#define res register int
using namespace std;
const int maxn=212;
int key[maxn];
int T,n,k;
int main(){
    scanf("%d",&T);
    while(T--){
        int ans=0;
        scanf("%d%d",&n,&k);
        for(res i=1;i<=k;i++) scanf("%d",&key[i]);
        ans=max(key[1]-1,n-key[k]);
        for(res i=2;i<=k;i++){
            int tmp=key[i]-key[i-1]-1;  
            if(tmp%2==0) tmp/=2;
            else tmp=tmp/2+1;
            ans=max(ans,tmp);
        }
	printf("%d\n",ans+1);
    }
    return 0;
}

说实话第一个太好想了qwq

Tea Queue #Codeforces 920B

Recently n students from city S moved to city P to attend a programming camp.

They moved there by train. In the evening, all students in the train decided that they want to drink some tea. Of course, no two people can use the same teapot simultaneously, so the students had to form a queue to get their tea.

i-th student comes to the end of the queue at the beginning of li-th second. If there are multiple students coming to the queue in the same moment, then the student with greater index comes after the student with lesser index. Students in the queue behave as follows: if there is nobody in the queue before the student, then he uses the teapot for exactly one second and leaves the queue with his tea; otherwise the student waits for the people before him to get their tea. If at the beginning of ri-th second student i still cannot get his tea (there is someone before him in the queue), then he leaves the queue without getting any tea.

For each student determine the second he will use the teapot and get his tea (if he actually gets it).

  • Input

The first line contains one integer t — the number of test cases to solve (1 ≤ t ≤ 1000).

Then t test cases follow. The first line of each test case contains one integer n (1 ≤ n ≤ 1000) — the number of students.

Then n lines follow. Each line contains two integer li, ri (1 ≤ li ≤ ri ≤ 5000) — the second i-th student comes to the end of the queue, and the second he leaves the queue if he still cannot get his tea.

It is guaranteed that for every condition li - 1 ≤ li holds.

The sum of n over all test cases doesn't exceed 1000.

Note that in hacks you have to set t = 1.

  • Output

For each test case print n integers. i-th of them must be equal to the second when i-th student gets his tea, or 0 if he leaves without tea.

Sample

Input
2
2
1 3
1 4
3
1 5
1 1
2 3
Output
1 2
1 0 2
  • 好像这两场第二题都是纯纯的模拟题
  • 思路就是以时间为遍历点,先将第i个正好与时间相符并站在队列开头的人压进队列,然后枚举队列里的每一个,把正好在时间点可以离队的人退出队列(要注意是在每一个时间节点下不断进行操作而非所有人一起操作)
  • 其实还挺好想的
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#define res register int
using namespace std;
const int maxn=1e3+12;
int l[maxn],r[maxn],ans[maxn];
int main(){
    int n,T;scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        memset(ans,0,sizeof(ans));
        for(res i=1;i<=n;i++) scanf("%d %d",&l[i],&r[i]);
        queue<int> q;
        int cnt=1;
        for(res i=1;i<=5000;i++){
            while(cnt<=n&&l[cnt]==i){
            	q.push(cnt++);
	    }
            while(q.size()&&r[q.front()]<i) q.pop();
            if(q.size()){
		ans[q.front()]=i;q.pop();
            }
        }
        for(int i=1;i<=n;i++) printf("%d ",ans[i]);
        cout<<endl;
    }
    return 0;
}

Swap Adjacent Elements #Codeforces 920C

You have an array a consisting of n integers. Each integer from 1 to n appears exactly once in this array.

For some indices i (1 ≤ i ≤ n - 1) it is possible to swap i-th element with (i + 1)-th, for other indices it is not possible. You may perform any number of swapping operations any order. There is no limit on the number of times you swap i-th element with (i + 1)-th (if the position is not forbidden).

Can you make this array sorted in ascending order performing some sequence of swapping operations?

  • Input

The first line contains one integer n (2 ≤ n ≤ 200000) — the number of elements in the array.

The second line contains n integers a1, a2, ..., an (1 ≤ ai ≤ 200000) — the elements of the array. Each integer from 1 to n appears exactly once.

The third line contains a string of n - 1 characters, each character is either 0 or 1. If i-th character is 1, then you can swap i-th element with (i + 1)-th any number of times, otherwise it is forbidden to swap i-th element with (i + 1)-th.

  • Output

If it is possible to sort the array in ascending order using any sequence of swaps you are allowed to make, print YES. Otherwise, print NO.

Sample

Input
6
1 2 5 3 4 6
01110
------------
6
1 2 5 3 4 6
01010
Output
YES
---------
NO

Note照样变没了,他很烦

思路就是只要有连着的1序列就将对应的数是为可交换的,不停sort就好了

这题好水不知道为什么放第三个

#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#define res register int
#define dd double
#define ll long long
using namespace std;
const int maxn=2*1e5+12;
int a[maxn];char s[maxn];
inline int qn(){
    int a=0,b=1;
    char px=getchar();
    while(px<'0'||px>'9'){
	if(px=='-') b=-1;
	px=getchar();
    }
    while(px>='0'&&px<='9'){
	a=a*10+px-'0';
	px=getchar();
    }
    return a*b;
}//2e5的数据好像不得不用quickin
inline int cmp(int a,int b) {return a<b;};
int main(){
    int n;scanf("%d",&n);
    for(res i=1;i<=n;i++) a[i]=qn();
    scanf("%s",s+1);
    for(res i=1;i<=n;i++){
	int st=0,ov=0;
	if(s[i]=='1'){
            st=i;
	    while(s[i]=='1'){
		i++;ov=i;
	    } 
	}
	sort(a+st,a+ov+1,cmp);
    }
    bool flag=true;
    for(res i=1;i<=n&&flag;i++){
	if(a[i]!=i) flag=false;
    }
    if(flag) printf("YES");
    else printf("NO"); 
    return 0;
}

 

 

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值