A. Ropewalkers
题意:给三个数,每次可以对一个数+1或-1,问最少多少次可以使得三个数两两之间距离>=d。
思路:水题,存进来的排个序,abc依次表示从小到大的。只要考虑b往两边距离满足题意即可。
view code
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include <queue>
#include<sstream>
#include <stack>
#include <set>
#include <bitset>
#include<vector>
#define FAST ios::sync_with_stdio(false)
#define abs(a) ((a)>=0?(a):-(a))
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define mem(a,b) memset(a,b,sizeof(a))
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define rep(i,a,n) for(int i=a;i<=n;++i)
#define per(i,n,a) for(int i=n;i>=a;--i)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<ll,ll> PII;
const int maxn = 1e5+200;
const int inf=0x3f3f3f3f;
const double eps = 1e-7;
const double pi=acos(-1.0);
const int mod = 1e9+7;
inline int lowbit(int x){return x&(-x);}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){d=a,x=1,y=0;}else{ex_gcd(b,a%b,d,y,x);y-=x*(a/b);}}//x=(x%(b/d)+(b/d))%(b/d);
inline ll qpow(ll a,ll b,ll MOD=mod){ll res=1;a%=MOD;while(b>0){if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}return res;}
inline ll inv(ll x,ll p){return qpow(x,p-2,p);}
inline ll Jos(ll n,ll k,ll s=1){ll res=0;rep(i,1,n+1) res=(res+k)%i;return (res+s)%n;}
inline ll read(){ ll f = 1; ll x = 0;char ch = getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch = getchar();}while(ch>='0'&&ch<='9') x = (x<<3) + (x<<1) + ch - '0', ch = getchar();return x*f; }
int dir[4][2] = { {1,0}, {-1,0},{0,1},{0,-1} };
ll arr[5];
int main()
{
ll a, b , c ,d;
cin>>arr[1]>>arr[2]>>arr[3]>>d;
sort(arr+1,arr+1+3);
a = arr[1] , b = arr[2], c = arr[3];
ll d1 = 0;
if(b - a < d) d1 += d - (b - a);
if(c - b < d) d1 += d - (c - b);
cout<<d1<<endl;
return 0;
}
B. Email from Polycarp
题意:s串为原串,判断t串是否是在s的基础上在使某若干位置的字符重复出现得到的。
思路:双指针简单模拟一下。p指向原串,q指向目标串。如果s[p] == t[q],就继续往下匹配。若不一样,只有两种可能:1.t串在重复上一个字符。 2. 完全失配,直接退出。 如果p走完了s串且t剩下来的全是重复的,就输出"YES"。否则都为"NO" 。
view code
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include <queue>
#include<sstream>
#include <stack>
#include <set>
#include <bitset>
#include<vector>
#define FAST ios::sync_with_stdio(false)
#define abs(a) ((a)>=0?(a):-(a))
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define mem(a,b) memset(a,b,sizeof(a))
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define rep(i,a,n) for(int i=a;i<=n;++i)
#define per(i,n,a) for(int i=n;i>=a;--i)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<ll,ll> PII;
const int maxn = 1e6+200;
const int inf=0x3f3f3f3f;
const double eps = 1e-7;
const double pi=acos(-1.0);
const int mod = 1e9+7;
inline int lowbit(int x){return x&(-x);}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){d=a,x=1,y=0;}else{ex_gcd(b,a%b,d,y,x);y-=x*(a/b);}}//x=(x%(b/d)+(b/d))%(b/d);
inline ll qpow(ll a,ll b,ll MOD=mod){ll res=1;a%=MOD;while(b>0){if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}return res;}
inline ll inv(ll x,ll p){return qpow(x,p-2,p);}
inline ll Jos(ll n,ll k,ll s=1){ll res=0;rep(i,1,n+1) res=(res+k)%i;return (res+s)%n;}
inline ll read(){ ll f = 1; ll x = 0;char ch = getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch = getchar();}while(ch>='0'&&ch<='9') x = (x<<3) + (x<<1) + ch - '0', ch = getchar();return x*f; }
int dir[4][2] = { {1,0}, {-1,0},{0,1},{0,-1} };
ll Map[500];
int main()
{
int kase;
cin>>kase;
while(kase--)
{
mem(Map,0);
string s; cin>>s;
string t; cin>>t;
for(int i=0; i<s.size();i++) Map[s[i]] ++;
int p = 0, q = 0;
while(p<s.size()&&q<t.size())
{
if(Map[t[q]]==0) break;
if(t[q] == s[p]) p++, q++;
else
{
if(q>0&&t[q] == t[q-1])
{
while(q<t.size()&&t[q]!=s[p]&&t[q]==t[q-1]) q++;
}
else break;
}
}
if(p<s.size())
{
cout<<"NO"<<'
';
}
else
{
int flag = 1;
if(q<t.size())
for(int i=q; i<t.size();i++) if(t[i]!=t[i-1]) flag = 0;
if(!flag)
cout<<"NO"<<'
';
else
cout<<"YES"<<'
';
}
}
return 0;
}
C1. Exam in BerSU (easy version)
题意:给出n个数,每个数会消耗t[i]的时间,问在m时限的情况下i前面要最少去掉多少人才能保证t[i]放得下
思路:贪心一下,要走的人最少的话肯定是让前面的用时大的人走最好。所以读入一个数就将前i-1个数排序一下。从大往小选即可。
view code
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include <queue>
#include<sstream>
#include <stack>
#include <set>
#include <bitset>
#include<vector>
#define FAST ios::sync_with_stdio(false)
#define abs(a) ((a)>=0?(a):-(a))
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define mem(a,b) memset(a,b,sizeof(a))
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define rep(i,a,n) for(int i=a;i<=n;++i)
#define per(i,n,a) for(int i=n;i>=a;--i)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<ll,ll> PII;
const int maxn = 1e5+200;
const int inf=0x3f3f3f3f;
const double eps = 1e-7;
const double pi=acos(-1.0);
const int mod = 1e9+7;
inline int lowbit(int x){return x&(-x);}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){d=a,x=1,y=0;}else{ex_gcd(b,a%b,d,y,x);y-=x*(a/b);}}//x=(x%(b/d)+(b/d))%(b/d);
inline ll qpow(ll a,ll b,ll MOD=mod){ll res=1;a%=MOD;while(b>0){if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}return res;}
inline ll inv(ll x,ll p){return qpow(x,p-2,p);}
inline ll Jos(ll n,ll k,ll s=1){ll res=0;rep(i,1,n+1) res=(res+k)%i;return (res+s)%n;}
inline ll read(){ ll f = 1; ll x = 0;char ch = getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch = getchar();}while(ch>='0'&&ch<='9') x = (x<<3) + (x<<1) + ch - '0', ch = getchar();return x*f; }
int dir[4][2] = { {1,0}, {-1,0},{0,1},{0,-1} };
ll t[maxn];
int main()
{
ll n = read(), m = read();
ll cur = 0;
rep(i,1,n)
{
ll x = read();
sort(t+1,t+i,greater<ll>());
ll p = 1; ll tmp = m - cur;
while(tmp < x) tmp += t[p], p++;
cout<<p-1<<' ';
t[i] = x;
cur += x;
}
cout<<'
';
return 0;
}
C2. Exam in BerSU (hard version)
题意:如上题。
思路:这题数据量加大很多,不能想C1那样莽了。仔细看数据发现t[i]<=100,这是个破题口。也就是说我们完全可以把上一题的思路顺延下来,排序的时候只需要在1~100出现过的数字进行排序就行了。所以我们用一个Map记录一下当前数有没有出现过,没出现过就加入all数组,Map同时计数这个数出现了多少次。然后拿到一个数就对前面的all数组排序(长度不会超过100),从大到小挑就行了。而且all[j]有多少个我们也是知道的,可以在O(1)时间内知道all[j]要挑多少。详见代码。
view code
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include <queue>
#include<sstream>
#include <stack>
#include <set>
#include <bitset>
#include<vector>
#define FAST ios::sync_with_stdio(false)
#define abs(a) ((a)>=0?(a):-(a))
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define mem(a,b) memset(a,b,sizeof(a))
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define rep(i,a,n) for(int i=a;i<=n;++i)
#define per(i,n,a) for(int i=n;i>=a;--i)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<ll,ll> PII;
const int maxn = 2e5+200;
const int inf=0x3f3f3f3f;
const double eps = 1e-7;
const double pi=acos(-1.0);
const int mod = 1e9+7;
inline int lowbit(int x){return x&(-x);}
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){if(!b){d=a,x=1,y=0;}else{ex_gcd(b,a%b,d,y,x);y-=x*(a/b);}}//x=(x%(b/d)+(b/d))%(b/d);
inline ll qpow(ll a,ll b,ll MOD=mod){ll res=1;a%=MOD;while(b>0){if(b&1)res=res*a%MOD;a=a*a%MOD;b>>=1;}return res;}
inline ll inv(ll x,ll p){return qpow(x,p-2,p);}
inline ll Jos(ll n,ll k,ll s=1){ll res=0;rep(i,1,n+1) res=(res+k)%i;return (res+s)%n;}
inline ll read(){ ll f = 1; ll x = 0;char ch = getchar();while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch = getchar();}while(ch>='0'&&ch<='9') x = (x<<3) + (x<<1) + ch - '0', ch = getchar();return x*f; }
int dir[4][2] = { {1,0}, {-1,0},{0,1},{0,-1} };
ll t[maxn];
vector<ll> all;
map<ll,ll> Map;
int main()
{
ll n = read(), m = read();
ll cur = 0;
rep(i,1,n)
{
ll x = read();
sort(all.begin(), all.end(), greater<ll>());
ll tmp = m - cur;
ll need = 0;
for(int j=0; j< all.size(); j++)
{
if(tmp >= x) break;
ll num = min(Map[all[j]] , ( x - tmp+all[j]-1)/all[j] );
need += num;
tmp += num * all[j];
}
cout<<need<<' ';
if(!Map[x]) all.pb(x);
Map[x]++;
cur += x;
}
cout<<'
';
return 0;
}