2020-04-01 12:08阅读: 512评论: 0推荐: 3

Codeforces Round #630 (Div. 2)

A. Exercising Walk (CF 1332 A)

题目大意

给定初始坐标(x,y)。有a次向左走(x1),有b次向右走(x+1),有c次向下走(y1),有d次向上走(y+1)。给定x1,y1,x2,y2,问是否存在一种走的序列,使得坐标(x,y)始终满足x1xx2,y1yy2

解题思路

判断x1xa+bx2,y1yc+dy2即可。

特别地当x1=x2的时候还要判断a,b是否同为0y同理。

神奇的代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int main(void) {
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int t;
cin>>t;
while(t--){
LL a,b,c,d,x,y,x1,y1,x2,y2;
cin>>a>>b>>c>>d>>x>>y>>x1>>y1>>x2>>y2;
LL xx=x+(b-a);
LL yy=y+(d-c);
bool qwq=0;
if (xx>=x1&&xx<=x2&&yy>=y1&&yy<=y2) qwq=true;
if (x1==x2&&(b!=0||a!=0)) qwq=false;
if (y1==y2&&(c!=0||d!=0)) qwq=false;
if (qwq) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
return 0;
}


B. Composite Coloring (CF 1332 B)

题目大意

t组询问,每组询问给定n合数ai,要求对n个数进行涂色,颜色数不超过11,要求相同颜色的任意两个数的最大公因数大于1。输出一种可行涂色方案,不要求最小化颜色数。保证有解。

解题思路

由于ai1000且为合数,得知ai的因数中至少有一个小于31的质数,因为如果都大于31的话,会有ai322=1024>1000ai1000矛盾。而31刚好是第11个质数,所以我们就看一个数最小质数是多少给它涂上相应的颜色就就好了。

(此处直接暴力)

神奇的代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
template <typename T>
void read(T &x) {
int s = 0, c = getchar();
x = 0;
while (isspace(c)) c = getchar();
if (c == 45) s = 1, c = getchar();
while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
if (s) x = -x;
}
template <typename T>
void write(T x, char c = ' ') {
int b[40], l = 0;
if (x < 0) putchar(45), x = -x;
while (x > 0) b[l++] = x % 10, x /= 10;
if (!l) putchar(48);
while (l) putchar(b[--l] | 48);
putchar(c);
}
int main(void) {
int t;
read(t);
while(t--){
int n;
read(n);
int qwq[1005]={0};
int ans[1005]={0};
int cnt=0;
for(int u,i=1;i<=n;++i){
read(u);
int up=sqrt(u);
bool qaq=false;
int tmp=u;
for(int j=2;j<u;++j){
if (u%j==0){
if (qwq[j]) {
ans[i]=qwq[j];
qaq=true;
break;
}
else if (tmp==u) tmp=j;
}
}
if (!qaq) ans[i]=qwq[tmp]=++cnt;
}
write(cnt,'\n');
for(int i=1;i<=n;++i){
printf("%d%c",ans[i],i==n?'\n':' ');
}
}
return 0;
}


C. K-Complete Word (CF 1332 C)

题目大意

给定一个只包含小写字母的字符串s及一个数字k(k|n),每次操作可以拿任意一个小写字母替换一个位置的上的小写字母。要求最小化操作次数,使得字符串变成

  • s是个回文串
  • si=si+k i[1,nk]

解题思路

目标串是一个由前缀串长度为k的重复nk次得到的。由于s1=sn=sk,类似的等式可以证明这个长度为k的前缀串也是个回文串。那么对于每个重复串,每个从1k2位,它们对应的字母一共有2×nk个,我们取出现次数最多的字母作为这个位的字母,这样保留的字母就尽可能的多,替换的操作就尽可能的少了。

k为奇数的时候中间那个位的字母就只有nk个。

神奇的代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
template <typename T>
void read(T &x) {
int s = 0, c = getchar();
x = 0;
while (isspace(c)) c = getchar();
if (c == 45) s = 1, c = getchar();
while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
if (s) x = -x;
}
template <typename T>
void write(T x, char c = ' ') {
int b[40], l = 0;
if (x < 0) putchar(45), x = -x;
while (x > 0) b[l++] = x % 10, x /= 10;
if (!l) putchar(48);
while (l) putchar(b[--l] | 48);
putchar(c);
}
int main(void) {
int t;
read(t);
while(t--){
int n,k;
read(n);
read(k);
char s[n+1]={0};
scanf("%s",s);
int ans=0;
int cu=(k>>1);
for(int i=0;i<cu;++i){
int cnt[28]={0};
int qwq=0;
for(int j=0;j<n/k;++j){
cnt[s[j*k+i]-'a']++;
cnt[s[(j+1)*k-i-1]-'a']++;
}
for(int j=0;j<26;++j) qwq=max(qwq,cnt[j]);
ans+=qwq;
}
if (k&1){
int cnt[28]={0};
for(int j=0;j<n/k;++j){
cnt[s[j*k+cu]-'a']++;
}
int qwq=0;
for(int j=0;j<26;++j) qwq=max(qwq,cnt[j]);
ans+=qwq;
}
ans=n-ans;
write(ans,'\n');
}
return 0;
}


D. Walk on Matrix (CF 1332 D)

题目大意

给定一个nm的网格,每个网格上有一个数字,每次可以向右(y+1)或向下(x+1)移动一格,要求一种移动方式,使得从(1,1)移动到(n,m),且到达的格子的所有数的&运算的值最大。

然而Bob写了个假DP,如图。
Bob的假DP

现在要求你构造一个矩阵,给定数字k(k105),满足以下要求:

  • 1n,m500
  • 0ai,j3105,for all 1in,1jm
  • 真正的答案与Bob的假答案的差值恰好为k

解题思路

构造题。从简入手。

首先1m的矩阵肯定不行,它们的差值为0

22的矩阵也不行,它们的差值为0

23的矩阵

(abcdef)

对于真正的答案,是max(abcf,abef,adef) (abcf表示a&b&c&f)。

对于Bob的答案,是max(abcf,max(abe,ade)f)

我们发现两者都有考虑到abcf,那么我们让abcf尽可能小,否则两个都会取abcf而使得差值为0。很显然我们让c0就可以了。

然后,Bob与真正的答案是少考虑了一种情况,我们假设adef这个情况恰好就是最大值的情况,Bob只考虑了abef,那就意味着abe>ade,但最终adef>abef,且adefabef=k,这样就能符合题目的要求了。

那我们要怎么诱导Bob选择abe呢。注意到kai的上限有3倍的差别。由于105在二进制下有16位,而3×10518位,我们让a前17位都是1a=262143),b的第17位是1,其他位是0b=131072),而d的前16位全是1d=131071),e=a,这样abe=131072>ade=131071,然后我们再让f=k,因为k在二进制下的第17位不可能是1,这样abef=0adef=k,就可以卡掉这个假DP了

(2621431310720131071262143k)

神奇的代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
template <typename T>
void read(T &x) {
int s = 0, c = getchar();
x = 0;
while (isspace(c)) c = getchar();
if (c == 45) s = 1, c = getchar();
while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
if (s) x = -x;
}
template <typename T>
void write(T x, char c = ' ') {
int b[40], l = 0;
if (x < 0) putchar(45), x = -x;
while (x > 0) b[l++] = x % 10, x /= 10;
if (!l) putchar(48);
while (l) putchar(b[--l] | 48);
putchar(c);
}
int main(void) {
int k;
read(k);
printf("2 3\n");
printf("262143 131072 0\n");
printf("131071 262143 %d\n",k);
return 0;
}


E. Height All the Same (CF 1332 E)

题目大意

给定一个nm的网格,每个格子上有若干个方块,可以进行以下两种操作:

  • 对于相邻的格子(共边),可以分别放上一个方块。
  • 对于一个格子,可以放上两个方块。

给定数字L,R,求出满足以下要求的初始局面的数量:

  • 每个格子初始的方块数aij满足LaijR
  • 通过若干次操作后可以使得所有格子的方块数相同(等高)。

解题思路

对于第二个操作,它不会改变一个格子上方块数的奇偶性。如果所有格子的奇偶性相同,那么通过若干个操作二就一定能达到等高。否则我们需要通过操作一来改变奇偶性。

如果我们要全变成偶数,而有一对相邻的格子的方块数是奇数,那么我们对这对格子进行操作一就能变成偶数。

如果一奇一偶,我们进行操作一,那么奇数数量方块的格子就会移动,如果还有一个奇数数量方块的格子,我们就可以把这个格子移动到同样是奇数数量方块的格子使它们相邻,然后再一次操作一变成偶数。

那就很显然了,如果初始局面里,只要奇数数量方块的格子数量是偶数,或者偶数数量方块的格子数量的偶数,这个局面就能得到等高的局面,而无关乎它们的位置。

那就是个简单的计数问题。在[L,R]中,我们可以填a个奇数,b个偶数。

nm是偶数,ans=0ini%2==0Cnmiaibnmi=(a+b)nm+(ab)nm2

nm是奇数,ans=0ini%2==0(Cnmiaibnmi+Cnmibianmi)=(a+b)nm

神奇的代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
template <typename T>
void read(T &x) {
int s = 0, c = getchar();
x = 0;
while (isspace(c)) c = getchar();
if (c == 45) s = 1, c = getchar();
while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
if (s) x = -x;
}
template <typename T>
void write(T x, char c = ' ') {
int b[40], l = 0;
if (x < 0) putchar(45), x = -x;
while (x > 0) b[l++] = x % 10, x /= 10;
if (!l) putchar(48);
while (l) putchar(b[--l] | 48);
putchar(c);
}
const LL mo=998244353;
LL qpower(LL a,LL b){
LL qwq=1;
while(b){
if (b&1) qwq=qwq*a%mo;
a=a*a%mo;
b>>=1;
}
return qwq;
}
LL inv(LL a){
return qpower(a,mo-2);
}
int main(void) {
LL n,m,l,r;
read(n);
read(m);
read(l);
read(r);
LL a=(r+1)/2-l/2;
LL b=r/2-(l-1)/2;
LL ans=0;
if (((n&1)==0)||((m&1)==0)) ans=(qpower(a+b,n*m)+qpower(a-b,n*m))%mo*inv(2)%mo;
else ans=qpower(a+b,n*m);
write(ans,'\n');
return 0;
}


这次才注意到resubmission会-50白白扣了3次qwq

本文作者:~Lanly~

本文链接:https://www.cnblogs.com/Lanly/p/12611629.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   ~Lanly~  阅读(512)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起
  1. 1 404 not found REOL
404 not found - REOL
00:00 / 00:00
An audio error has occurred.