Codeforces Round 776
5
abcde
c
abcde
b
x
y
aaaaaaaaaaaaaaa
a
contest
t
output
YES
NO
NO
YES
题意:
你可以删除相邻的两个字符,问多次操作后能不呢剩下一个字符为 c c c
每个测试给你一个字符串 s s s和一个字符 c c c
题解:
不难看出每次删除必定有一个偶数位的字符,那么反过来,如果该字符只出现在字符串 s s s的偶数位或者没出现那么一定NO
如果出现在了奇数位,那么最后就可以
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define IOS {std::ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);}
#define x first
#define y second
#define int long long
#define end(x) {cout<<x<<'\n';return ;}
#define endy {cout<<"YES\n";return ;}
#define endn {cout<<"NO\n"; return ;}
using namespace std;
typedef pair<int,int> PII;
typedef long long ll;
const int N =2*1e5+10;
string s;int n,x,y,i,j,k,l,r;float f;
char ch;
int a[N],b[N];
struct node{
int x,i;
};
void solve();
void solve(){
cin>>s>>ch;
if(s.size()==1) { if (ch != s[0]) endn else endy}//可以不写这一行,(当时特判了,后知后觉)
for(i=0;i<s.size();i++)
if(s[i]==ch&&((i+1)&1))endy
endn
}
signed main(){
//IOS
int _=1;
cin>>_;
while(_--)solve();
}
5
1 4 3
5 8 4
6 10 6
1 1000000000 1000000000
10 12 8
output
2
4
5
999999999
5
题意:
给你一个区间的左右端点 l , r l,r l,r,和一个数字 a a a
f a ( x ) = ( x / a ) ( 向下取整 ) + x m o d a f_a(x)=(x/a)(向下取整)+x \mod a fa(x)=(x/a)(向下取整)+xmoda
问 max f a ( x ) x ∈ [ l , r ] \max f_a(x) x\in[l,r] maxfa(x)x∈[l,r]
题解:
首先考虑 x m o d a x\mod a xmoda最大,
其实考虑 x x x最大
最后取最大值
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define IOS {std::ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);}
#define x first
#define y second
#define int long long
#define end(x) {cout<<x<<'\n';return ;}
#define endy {cout<<"YES\n";return ;}
#define endn {cout<<"NO\n"; return ;}
using namespace std;
typedef pair<int,int> PII;
typedef long long ll;
const int N =2*1e5+10;
//string s;int n,x,y,i,j,k,l,r;float f;
//char ch;
//int a[N],b[N];
struct node{
int x,i;
};
void solve();
void solve(){
int l,r,a;
cin>>l>>r>>a;
int ans=r / a + r % a;
int ans2=r / a * a - 1;
if(ans2>=l)
ans = max( ans, ans2 / a + ans2 % a );
cout<<ans<<endl;
}
signed main(){
//IOS
int _=1;
cin>>_;
while(_--)solve();
}
3
3 8
0 10
-2 1
4 10
11 20
7 -1
9 1
2 3
5 -2
3 6
-1 2
1 3
3 -1
2 4
4 0
8 2
2 5
5 -1
3 -2
1 0
-2 0
-5 -3
output
12
2 6
5 1
7 8
10
1 6
5 2
3 4
-6
5 1
4 2
题意:
给出 n n n, m m m
随后给出 m m m个坐标点和其权值
你需要给出 n n n个区间 [ l 1 , r 1 ] , [ l 2 , r 2 ] , . . . , [ l n , r n ] [l_1,r_1],[l_2,r_2],...,[l_n,r_n] [l1,r1],[l2,r2],...,[ln,rn]
要满足 i , j ( 1 ≤ i ≤ j ≤ n ) i,j(1\leq i \leq j \leq n) i,j(1≤i≤j≤n)使得 l i < l j < r j < r i l_i < l_j < r_j < r_i li<lj<rj<ri
求满足以上条件的区间 min ∑ k = 1 n f ( k ) \min \sum_{k=1}^nf(k) min∑k=1nf(k), f ( x ) = w l x + w r x , w i 是 i 点的权值 f(x)=w_{l_x}+w_{r_x},w_i是i点的权值 f(x)=wlx+wrx,wi是i点的权值
简单来说就是找到 n n n个区间,区间之间构成严格包含关系,因为可以取很多种这样的区间,求构成区间的全部点的权值和的最小值
题解:
直接贪心,给权值排序
然后取点,在前 2 n 2n 2n个点之中排序(按照坐标大小),求和
最后打印点的编号即可第一个排序可以保证权值求和后最小,第二个排序可以保证区间是严格包含关系
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define IOS {std::ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);}
#define x first
#define y second
#define int long long
#define end(x) {cout<<x<<'\n';return ;}
#define endy {cout<<"YES\n";return ;}
#define endn {cout<<"NO\n"; return ;}
using namespace std;
typedef pair<int,int> PII;
typedef long long ll;
const int N =2*1e5+10;
//string s;int n,x,y,i,j,k,l,r;float f;
//char ch;
//int a[N],b[N];
struct node{
int x,w;
int i;
};
void solve();
node a[N];
int n,m;
void solve(){
cin>>n>>m;
for(int i=1;i<=m;i++){
cin>>a[i].x>>a[i].w;
a[i].i=i;
}
sort(a+1,a+m+1,[&](node a,node b){return a.w<b.w;});
int ans=0;
for(int i=1;i<=n*2;i++)ans+=a[i].w;
sort(a+1,a+n*2+1,[&](node a,node b){return a.x<b.x;});
cout<<ans<<'\n';
for(int i=1;i<=n;i++){
cout<<a[i].i<<' '<<a[n*2-i+1].i<<'\n';
}
cout<<'\n';
}
signed main(){
//IOS
int _=1;
cin>>_;
while(_--)solve();
}
3
6
3 2 5 6 1 4
3
3 1 2
8
5 8 1 3 2 6 4 7
output
0 1 1 2 0 4
0 0 1
0 1 2 0 2 5 6 2
题意:
有一个排列放在数组 a a a,有 n n n次操作,第 x x x次操作可以右移 k k k次 a [ 1 , 2 , . . , x ] a[1,2,..,x] a[1,2,..,x]
现在给你操作 n n n次的数组 b b b,问你 n n n次操作分别都右移了多少次
题解:
其实反过来想就是第 n n n次操作会改变数字 n n n在数组里的原始位置,如果不右移则不动,直接反过来模拟计算即可
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define IOS {std::ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);}
#define x first
#define y second
#define int long long
#define end(x) {cout<<x<<'\n';return ;}
#define endy {cout<<"YES\n";return ;}
#define endn {cout<<"NO\n"; return ;}
using namespace std;
typedef pair<int,int> PII;
typedef long long ll;
const int N =2*1e5+10;
//string s;int n,x,y,i,j,k,l,r;float f;
//char ch;
//int a[N],b[N];
struct node{
int x,w;
int i;
};
void solve();
int a[N],b[N];
int n,m;
void solve(){
cin>>n;
for(int i=0;i<n;i++)cin>>a[i];
for(int i=n-1;i>=0;i--){
b[i] = find(a,a+n,i+1)-a ;
rotate(a,a+b[i]+1,a+i+1);
b[i] = (b[i]+1)%(i+1);
}
for(int i=0;i<n;i++)cout<<b[i]<<" \n"[i==n-1];
}
signed main(){
//IOS
int _=1;
cin>>_;
while(_--)solve();
}
9
3 12
3 5 9
2 5
1 5
2 100
1 2
5 15
3 6 9 12 15
3 1000000000
1 400000000 500000000
2 10
3 4
2 2
1 2
4 15
6 11 12 13
2 20
17 20
output
2
1
1
2
99999999
3
0
1
9
题意:
总共 m m m天,有 n n n次考试,给出 n n n次考试的时间
你可以调整一次考试时间,问最短休息时间(考试前的空闲时间)的最大值为多少
题解:
修改休息时间最短的那次考试,可以放在最后或者放在最长休息时间的中间
取改变和不改变的最大值
并且注意,大多数变体中的最小中断是相同的 — 初始时间表中的最小值。所以为了减少 μ μ μ
,您需要准确地移动形成它的两项考试之一,并且您需要检查两个选项中哪一个更好。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define IOS {std::ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);}
#define x first
#define y second
#define int long long
#define end(x) {cout<<x<<'\n';return ;}
#define endy {cout<<"YES\n";return ;}
#define endn {cout<<"NO\n"; return ;}
using namespace std;
typedef pair<int,int> PII;
typedef long long ll;
const int N =2*1e5+10;
const int inf = 0x3f3f3f3f;
//string s;int n,x,y,i,j,k,l,r;float f;
//char ch;
//int a[N],b[N];
void solve();
int f(int x);
int a[N];
int n,d;
int f(int x){
int maxn=0,minn=d;
int last_i=0;
for(int i=1;i<=n;i++){
if(i==x)continue;
maxn=max(maxn, a[i]-a[last_i]-1);
minn=min(minn, a[i]-a[last_i]-1);
last_i=i;
}
return min(minn,max(d-a[last_i]-1,((maxn-1)/2)));
}
void solve() {
cin >> n >> d;
int min_ans_i = 1;
for (int i = 1; i <= n; i++) {
cin >> a[i];
if (a[min_ans_i] - a[min_ans_i - 1] - 1 > a[i] - a[i - 1] - 1)min_ans_i = i;
}
int ans=f(min_ans_i);
if(min_ans_i>1)
ans = max (ans,f(min_ans_i-1));
cout<<ans<<'\n';
}
signed main(){
IOS
int _=1;
cin>>_;
while(_--)solve();
}