Codeforces Round #641 (Div. 2) 补题
A. Orac and Factors
一个偶数每次操作后都会加2,一个奇数第一次操作后会变成偶数
代码
#pragma GCC optimize(2)
#include <iostream>
#include<vector>
#include<map>
#include<queue>
#include<set>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<stdlib.h>
#include<cmath>
#include<stdio.h>
#include<utility>
#define INF 0x3f3f3f3f
typedef long long int ll;
using namespace std;
ll mod = 1e9 + 7;
inline void read(int &p)
{
p=0;int flag=1;char c=getchar();
while(!isdigit(c)) {if(c=='-') flag=-1;c=getchar();}
while(isdigit(c)) {p=p*10+c-'0';c=getchar();}p*=flag;
}
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int t;
cin>>t;
while(t--){
int n, k;
read(n), read(k);
ll ans = 0;
if(n%2 == 0){
ans = 1ll*n + 1ll*2*k;
}
else{
ll div = n;
for(int i=2;i*i<=n;i++){
if(n%i == 0){
div = i;
break;
}
}
ans = n + div + 1ll*2*(k-1);
}
cout<<ans<<"\n";
}
return 0;
}
B. Orac and Models
用动态规划的方法,mx[i]代表从第i个数出发能得到的最大结果。从后向前遍历,对于第i个元素a[i],遍历每次走一步,每次走两步....能得到的值,例如能从i走到j,那么有转移方程mx[i] = max(mx[i], mx[j] + 1)
代码
#pragma GCC optimize(2)
#include <iostream>
#include<vector>
#include<map>
#include<queue>
#include<set>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<stdlib.h>
#include<cmath>
#include<stdio.h>
#include<utility>
#define INF 0x3f3f3f3f
typedef long long int ll;
using namespace std;
ll mod = 1e9 + 7;
inline void read(int &p)
{
p=0;int flag=1;char c=getchar();
while(!isdigit(c)) {if(c=='-') flag=-1;c=getchar();}
while(isdigit(c)) {p=p*10+c-'0';c=getchar();}p*=flag;
}
int a[100050];
int mx[100050];
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int t;
cin>>t;
while(t--){
int n;
read(n);
for(int i=1;i<=n;i++) scanf("%d", &a[i]);
int ans = 0;
for(int i=n;i>=1;i--){
mx[i] = 1;
for(int j=i+i;j<=n;j+=i){
if(a[j] > a[i])
mx[i] = max(mx[i], mx[j] + 1);
}
ans = max(ans, mx[i]);
}
//for(int i =1;i<=n;i++) cout<<mx[i]<<endl;
cout<<ans<<"\n";
}
return 0;
}
C. Orac and LCM
我的方法好像比较麻烦。。。
以4,6,,9为例
| | 4 | 6 | 9 |
| 2 | 2 | 1 | 0 |
| 3 | 0 | 1 | 2 |
用这个格子表示每个数中含有某个素因数的个数,比如4里面有2个2,0个3。考虑对任意两个数取lcm对素因数的影响,比如对4和6取lcm,所得到的数中因数2的个数就是max(2, 1)=2,6和9取lcm所得到的数中素因数2的个数是max(1,0)=0。而取lcm所得到的集合取gcd保留的素因数2的个数就是所有数含素因数2的个数的最小值,所以我们就可以考虑求出在对任意两数取lcm后可以得到的每个素因数的最小值,如果把每个数含素因数2的个数放进一个数组,那么在取gcd时2对答案的贡献就是这个数组中倒数第二小的值(因为最小值和次小值也会取一次lcm保留次小值)。至此我们可以想到,对每个元素分解素因数,记录每种素因数的次小个数,最后所有素因数按次小个数乘起来就是答案。
代码
#pragma GCC optimize(2)
#include <iostream>
#include<vector>
#include<map>
#include<queue>
#include<set>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<stdlib.h>
#include<cmath>
#include<stdio.h>
#include<utility>
#define INF 0x3f3f3f3f
typedef long long int ll;
using namespace std;
ll mod = 1e9 + 7;
inline void read(int &p)
{
p=0;int flag=1;char c=getchar();
while(!isdigit(c)) {if(c=='-') flag=-1;c=getchar();}
while(isdigit(c)) {p=p*10+c-'0';c=getchar();}p*=flag;
}
int gcd(int a, int b){
return b==0?a:gcd(b, a%b);
}
int a[100050];
int mi[200050], _mi[200050];
int sz[200050];
int mx = 0;
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int n;
cin>>n;
memset(mi, INF, sizeof(mi));
memset(_mi, INF, sizeof(_mi));
for(int i=1;i<=n;i++){
read(a[i]);
mx = max(mx, a[i]);
int t = a[i];
for(int j=2;j*j<=t;j++){
int num = 0;
while(a[i]%j==0){
a[i] /= j;
num++;
}
if(num < mi[j]){
_mi[j] = mi[j];
mi[j] = num;
}
else _mi[j] = min(_mi[j], num);
sz[j]++;
}
if(a[i]!=1){
int num = 1;
int j = a[i];
if(num < mi[j]){
_mi[j] = mi[j];
mi[j] = num;
}
else _mi[j] = min(_mi[j], num);
sz[a[i]]++;
}
}
ll ans = 1;
for(int i=1;i<=mx;i++){
if(sz[i] == n) ans *= 1ll*pow(i, _mi[i]);
else if(sz[i] == n-1) ans *= 1ll*pow(i, mi[i]);
}
cout<<ans<<endl;
return 0;
}
D. Orac and Medians
这题的模型就和病毒传播一样。。。
因为大小只是相对关系,读入数据时比k大的元素记为2,等于k的记为1,小于k的记为0
如果数组里不含1,那么肯定是不满足的
如果连着的三个数中有两个大于零的元素,那么我们就可以把剩下的那个元素也变成大于零的数,在这样的操作下,如果数组中元素是0,0,x,1,0,0,0重复这样的操作我们就可以把所有元素变为1(x>0),如果数组是2,2,0,0,0,1,0,0虽然2与1距离很远,但我们可以通过上述操作把数组变成2,2,2,2,2,1,0,0之后我们就可以把数组变成全1
所以这道题在判断有没有1之后判断数组中有没有两个大于零的元素,他们距离小于等于2
代码
#pragma GCC optimize(2)
#include <iostream>
#include<vector>
#include<map>
#include<queue>
#include<set>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<stdlib.h>
#include<cmath>
#include<stdio.h>
#include<utility>
#define INF 0x3f3f3f3f
typedef long long int ll;
using namespace std;
ll mod = 1e9 + 7;
inline void read(int &p)
{
p=0;int flag=1;char c=getchar();
while(!isdigit(c)) {if(c=='-') flag=-1;c=getchar();}
while(isdigit(c)) {p=p*10+c-'0';c=getchar();}p*=flag;
}
int a[100005];
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int t;
cin>>t;
while(t--){
int n, k;
cin>>n>>k;
bool flag = false;
for(int i=1;i<=n;i++){
int v;
read(v);
if(v == k) a[i] = 1;
else if(v > k) a[i] = 2;
else a[i] = 0;
if(v == k) flag = true;
}
if(!flag){
printf("no\n");
continue;
}
if(n==1){
printf("yes\n");
continue;
}
flag = false;
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n&&j-i<=2;j++){
if(a[i]&&a[j]){
flag = true;
break;
}
}
if(flag) break;
}
if(flag) printf("yes\n");
else printf("no\n");
}
return 0;
}
E. Orac and Game of Life
如果一个数能变色,那么他就一直能变色(因为相邻的格子也在一起变色),如果一个格子不能变色,那么会变色的格子在几轮之后可能会“传播”到他这里,让他能够变色,所以这个题就是统计每个格子最少几轮后开始变色
代码
#pragma GCC optimize(2)
#include <iostream>
#include<vector>
#include<map>
#include<queue>
#include<set>
#include<cstdio>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<stdlib.h>
#include<cmath>
#include<stdio.h>
#include<utility>
#define INF 0x3f3f3f3f
typedef long long int ll;
using namespace std;
ll mod = 1e9 + 7;
inline void read(int &p)
{
p=0;int flag=1;char c=getchar();
while(!isdigit(c)) {if(c=='-') flag=-1;c=getchar();}
while(isdigit(c)) {p=p*10+c-'0';c=getchar();}p*=flag;
}
int n, m, t;
int a[1005][1005], mi[1005][1005];
bool vis[1005][1005];
int mx[4] = {0, 0, 1, -1}, my[4] = {1, -1, 0, 0};
queue<int> q;
void bfs(){
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
for(int k=0;k<4;k++){
int xx = i + mx[k];
int yy = j + my[k];
if(xx<1||xx>n||yy<1||yy>m) continue;
if(a[i][j]==a[xx][yy]){
vis[i][j] = 1;
mi[i][j] = 0;
q.push(i), q.push(j);
break;
}
}
}
}
while(!q.empty()){
int x = q.front(); q.pop();
int y = q.front(); q.pop();
for(int k=0;k<4;k++){
int xx = x + mx[k];
int yy = y + my[k];
if(vis[xx][yy]||xx<1||xx>n||yy<1||yy>m) continue;
vis[xx][yy] = 1;
mi[xx][yy] = mi[x][y] + 1;
q.push(xx), q.push(yy);
}
}
}
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
cin>>n>>m>>t;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
char v;
cin>>v;
a[i][j] = v - '0';
mi[i][j] = INF;
}
}
bfs();
while(t--){
int x, y;
ll p;
cin>>x>>y>>p;
if(mi[x][y]>p||mi[x][y]==INF||(p+mi[x][y])%2==0){//cout<<p+mi[x][y]<<"m"<<endl;
printf("%d\n", a[x][y]);
continue;
}
else printf("%d\n", !a[x][y]);
}
return 0;
}

浙公网安备 33010602011771号