Codeforces Round #704 (Div. 2)——A~D

A. Three swimmers

Three swimmers decided to organize a party in the swimming pool! At noon, they started to swim from the left side of the pool.
It takes the first swimmer exactly 𝑎 minutes to swim across the entire pool and come back, exactly 𝑏 minutes for the second swimmer and 𝑐 minutes for the third. Hence, the first swimmer will be on the left side of the pool after 0, 𝑎, 2𝑎, 3𝑎, … minutes after the start time, the second one will be at 0, 𝑏, 2𝑏, 3𝑏, … minutes, and the third one will be on the left side of the pool after 0, 𝑐, 2𝑐, 3𝑐, … minutes.
You came to the left side of the pool exactly 𝑝 minutes after they started swimming. Determine how long you have to wait before one of the swimmers arrives at the left side of the pool.
Input
The first line of the input contains a single integer 𝑡 (1≤𝑡≤1000) — the number of test cases. Next 𝑡 lines contains test case descriptions, one per line.
Each line contains four integers 𝑝, 𝑎, 𝑏 and 𝑐 (1≤𝑝,𝑎,𝑏,𝑐≤1018), time in minutes after the start, when you came to the pool and times in minutes it take the swimmers to cross the entire pool and come back.
Output
For each test case, output one integer — how long you have to wait (in minutes) before one of the swimmers arrives at the left side of the pool.
Example
input
4
9 5 4 8
2 6 10 9
10 2 5 10
10 9 9 9
output
1
4
0
8

AC代码:

#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
int main()
{
  int t;
  cin>>t;
  while(t--){
    ll p, a, b, c;
    cin>>p>>a>>b>>c;
    ll x=(p/a+bool(p%a))*a-p;
    ll y=(p/b+bool(p%b))*b-p;
    ll z=(p/c+bool(p%c))*c-p;
    ll ans=min( x, y );
    ans=min( ans, z );
    cout<<ans<<endl;
  }
}

B. Card Deck

在这里插入图片描述
Example
input
4
4
1 2 3 4
5
1 5 2 4 3
6
4 2 5 3 6 1
1
1
output
4 3 2 1
5 2 4 3 1
6 1 5 3 4 2
1

题解:
类似出栈的思想。
每次不需查找栈中剩余元素的最大值,只需设一个bool数组,下标从n~1,若bool值为0表示已出栈,否则从该值所在位置输出。另设一个数组存储的下标。

AC代码:

#include <string.h>
#include <iostream>
using namespace std;
typedef long long ll;
int main()
{
    cin.tie(0);std::ios::sync_with_stdio(false);
    int t;
    cin>>t;
    while(t--){
        int n;
        cin>>n;
        int p[n+10], id[n+10];
        for(int i=1; i<=n; i++) { 
            cin>>p[i]; 
            id[p[i]]=i;
        }
		int m=n+1;
        while(--m){
			for(int i=id[m]; p[i] && i<=n ; i++){
				cout<<p[i]<<" ";
				p[i]=0;
			}
		}
        cout<<endl;
    }
    return 0;
}

C. Maximum width

在这里插入图片描述
Examples
input
5 3
abbbc
abc
output
3
input
5 2
aaaaa
aa
output
4
input
5 5
abcdf
abcdf
output
1

题解:
贪心法。即求相邻的两个元素的最大相差。可分别设两组数组表示t中每个元素在s中最早出现的位置和最晚出现的位置,再相减。

AC代码:

#include <string.h>
#include<algorithm>
#include <iostream>
using namespace std;
typedef long long ll;
const int maxn=2*1e5+10;
int main()
{
    cin.tie(0);std::ios::sync_with_stdio(false);
    int n, m;
    cin>>n>>m;
    string s,t;
    cin>>s>>t;
    int ans=0;
    int ff[m+10],ll[m+10];
    for(int i=0, j=0; i<m && j<n; i++){
        while(t[i]!=s[j] ) j++;
        ff[i]=j++;
    }
    for(int i=m-1, j=n-1; i>=0 && j>=0; i--){
        while(t[i]!=s[j]) j--;
        ll[i]=j--;
    }
    for(int i=0; i<m-1; i++){
        ans=max( ans, ll[i+1]-ff[i] );
    }
    cout<<ans<<endl;
    return 0;
}

D. Genius’s Gambit

在这里插入图片描述
Examples
1、input
4 2 3
output
Yes
101000
100001
2、input
3 2 5
output
No

题解:
寻找规律,以及对诸多特殊情况的考虑。WAn次…
规律一开始找复杂了,实际上特别简单。
假设x以最简单的形式排列,从左到右依次b个1和a个0。只需要讨论k的值得到y的一种情况
(1)k>a+b-2,直接NO
(2)k=0,y=x
(3)0<k<=a,令y第b位为0,第b+k为1
(4)a<k<=a+b-2,令y第n位为1,第b-(k-a)为0
注意no的情况有很很多需要判断排除。

AC代码:

#include <string.h>
#include <math.h>
#include<algorithm>
#include <stdio.h>
#include <iostream>
using namespace std;
typedef long long ll;
const int maxn=2*1e5+10;
int main()
{
    cin.tie(0);std::ios::sync_with_stdio(false);
    int a, b, k;
    cin>>a>>b>>k;
    int n=a+b;
    if( ( k>n-2 && n-2>=0 ) || ( a==0 && k!=0 ) || (b==1 && k!=0 ) ) { cout<<"No"<<endl; return 0; }
    else cout<<"Yes"<<endl;
    if( a==0 && b==1 && k==0 ) { cout<<"1"<<endl<<"1"<<endl; return 0; }
    int ans[n+10];
    for(int i=0; i<n; i++) {
        if(i<b) { ans[i]=1; cout<<"1"; }
        else { ans[i]=0; cout<<"0"; }
    }
    cout<<endl;
    if( k<=a && k>0 ) {
        ans[b-1]=0;
        ans[b+k-1]=1;
    }
    else if(k>a){
        ans[n-1]=1;
        ans[b-1-(k-a)]=0;
    }
    for(int i=0; i<n; i++) cout<<ans[i];
    cout<<endl;
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值