文章目录

  • 前言
  • CF1104A Splitting into digits
    • Description\text{Description}Description
    • Solution\text{Solution}Solution
    • Description\text{Description}Description
  • CF1104B Game with string
    • Description\text{Description}Description
    • Solution\text{Solution}Solution
    • Code\text{Code}Code
  • CF1103A Grid game
    • Description\text{Description}Description
    • Solution\text{Solution}Solution
    • Code\text{Code}Code
  • CF1103B Game with modulo
    • Description\text{Description}Description
    • Solution\text{Solution}Solution
    • Code\text{Code}Code
  • CF1103C Johnny Solving
    • Description\text{Description}Description
    • Solution\text{Solution}Solution
    • Code\text{Code}Code
  • CF1103D Professional layer
    • Description\text{Description}Description
    • Solution\text{Solution}Solution
    • Code\text{Code}Code

前言

1104AB,1103A是水题
1103B是不错的交互题
C小清新构造
D毒瘤优化状压
E是恶心数学题(直接弃疗)

CF1104A Splitting into digits

Description\text{Description}Description

给定一个数字 nnn ,请将它拆分成 a1+a2+⋯+am,ai∈[1,9]a_1+a_2+\cdots + a_m,a_i \in [1,9]a1​+a2​+⋯+am​,ai​∈[1,9],使得 ∑i=1mai=n\sum_{i=1}^ma_i = n∑i=1m​ai​=n,并且使 aia_iai​ 中不同的数尽量少。

输出方案,两行,第一行为数的个数 mmm,第二行为mmm个数,由空格隔开,分别为 a1−ama_1 - a_ma1​−am​。

Solution\text{Solution}Solution

智障题。输出 nnn 个 111 即可…

Description\text{Description}Description

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1e6+100;
inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}
int n;
int main(){n=read();for(int i=1;i<=9;i++){if(n%i==0){printf("%d\n",n/i);while(n) printf("%d ",i),n-=i;return 0;}}printf("%d\n",(n+8)/9);while(n>9) printf("9 ");n-=9;printf("%d",n);
}

CF1104B Game with string

Description\text{Description}Description

A\text{A}A 与 B\text{B}B 正在玩一个关于由小写拉丁字符构成的字符串 sss 的游戏。

每一个人会轮流操作,先 A\text{A}A 后 B\text{B}B。

对于每一次操作,操作者需要将 sss 中的两个 连续且相同 的字符消除,消除后的字符串由另一个人操作。

对于每一次操作,如果不能找到两个符合要求的字符,那么操作者输。

Solution\text{Solution}Solution

水题。
显然博弈论只是层皮,胜负就与操作次数的奇偶性有关。
由于有删除操作,我写了个链表,每次删除后再递归往两侧看能不能接着删。
看其他题解许多使用了栈,做法也很简单。

Code\text{Code}Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1e5+100;
inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}
int n;
int l[N],r[N],ans;
char s[N];
bool vis[N];
void del(int x,int y){++ans;vis[x]=vis[y]=1;int xx=l[x],yy=r[y];r[xx]=yy;l[yy]=xx;if(xx>0&&yy<=n&&s[xx]==s[yy]) del(xx,yy);return;
}
int main(){scanf(" %s",s+1);n=strlen(s+1);for(int i=1;i<=n;i++) l[i]=i-1,r[i]=i+1;r[0]=1;l[n+1]=n;for(int i=1;i<=n;i++){if(vis[i]) continue;if(s[i]==s[l[i]]) del(l[i],i);}if(ans&1) printf("Yes");else printf("No");
}

CF1103A Grid game

Description\text{Description}Description

你有一个 4×44\times44×4 的棋盘和一些 1×21\times21×2 大小的方格,给你放入的顺序,000 表示竖着放,111 表示横着放,每当一行或一列全放满时会将这一行或列上的消除,输出任意一种使小方格不重叠的方案。

Solution\text{Solution}Solution

似乎和其他题解的方法不太一样。
竖着的先放 (1,1)(1,1)(1,1),再放 (3,1)(3,1)(3,1) 把上一个消掉。
横着的先放 (4,3)(4,3)(4,3),再放 (4,1)(4,1)(4,1) 把上一个消掉。
永远不会有冲突。

Code\text{Code}Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1e5+100;
inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}
int n;
int a,b;
char s[N];
int main(){scanf(" %s",s+1);n=strlen(s+1);for(int i=1;i<=n;i++){if(s[i]=='0'){if(a) printf("3 1\n");else printf("1 1\n");a^=1;}else{if(b) printf("4 1\n");else printf("4 3\n");b^=1;}}
}

CF1103B Game with modulo

Description\text{Description}Description

未知一个数 aaa,让你每次猜两个数 xxx 和 yyy,若 (xmoda)≥(ymoda)(x\bmod a)\ge (y\bmod a)(xmoda)≥(ymoda) 返回 x,否则返回 y。让你猜测次数少于 606060 次的时候猜出数 aaa。
a≤2×109a\le 2\times 10^9a≤2×109

Solution\text{Solution}Solution

一开始,令 x=1x=1x=1。
不断进行一下过程:

  1. 询问 xxx 与 2x2x2x。
  2. 若 xmoda<2xmodax\bmod a< 2x\bmod axmoda<2xmoda,说明 a>2xa>2xa>2x,令 x←2xx\gets 2xx←2x,回到第一步。
  3. 若 xmoda>2xmodax\bmod a> 2x\bmod axmoda>2xmoda,说明 a≤2xa\le 2xa≤2x,也就是 a∈(x,2x]a\in (x,2x]a∈(x,2x],进入第四步。
  4. 现在已知 a∈(x,2x]a\in (x,2x]a∈(x,2x],二分找到 aaa 的值即可。

a=1a=1a=1 的情况比较恶心,建议特判处理。

Code\text{Code}Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
const int N=4e5+100;
inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c)) {x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}
int n,m;
char c;
inline char ask(int x,int y){printf("? %d %d\n",x,y);fflush(stdout);scanf(" %c",&c);return c;
}
char s[105];
signed main(){#ifndef ONLINE_JUDGE//freopen("a.in","r",stdin);//freopen("a.out","w",stdout);
#endif    while(1){scanf(" %s",s+1);if(s[1]=='m'||s[1]=='e') return 0;int x=1;while(1){if(ask(x,x<<1)=='x') break;else x<<=1;}if(x==1){if(ask(2,1)=='y') printf("! 2\n");else printf("! 1\n");fflush(stdout);}else{int st=x+1,ed=x<<1;while(st<ed){int mid=(st+ed)>>1;if(ask(mid,x)=='x') st=mid+1;else ed=mid;}printf("! %d\n",st);fflush(stdout);}}return 0;
}
/**/

CF1103C Johnny Solving

Description\text{Description}Description

给出一张无重边的无向图(保证每个点度数大于等于 333)和一个限制 kkk,需要你构造以下两种情况中的一种:

1、找出一条路径长度为 n/kn/kn/k。

2、找出 kkk 个环,使得每个环的长度大于 333 而且不是 333 的倍数,并且要求保证每个环中至少有一个点在这 kkk 个环里只出现一次。

Solution\text{Solution}Solution

不错的一道题。
不难想到先建出 dfs 生成树的套路。
然后,若直径大于 n/kn/kn/k,就已经满足条件一了。
否则,必然有每个结点的深度不超过 n/kn/kn/k,那么叶子的数量必然不少于 kkk 个。
同时,每个叶子 uuu 必然至少有两条非树返祖边。,假设分别连向 x,yx,yx,y。
分类讨论一下一定有一个不是 333 的倍数的环。
把叶子作为代表结点即可。

Code\text{Code}Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
const int N=5e5+100;
inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c)) {x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}
int n,m,k;
struct node{int to,nxt;
}p[N<<1];
int fi[N],cnt;
inline void addline(int x,int y){p[++cnt]=(node){y,fi[x]};fi[x]=cnt;return;
}
bool vis[N],jd[N];
vector<int>v[N];
int fa[N],dep[N];
void dfs(int x,int f){fa[x]=f;dep[x]=dep[f]+1;vis[x]=1;for(int i=fi[x];~i;i=p[i].nxt){int to=p[i].to;if(to==f) continue;if(vis[to]){if(dep[to]<dep[x]) v[x].push_back(to);      }else{jd[x]=1;dfs(to,x);}}return;
}
void print(int x,int tp){//printf("%d\n",dep[x]-dep[tp]+1);while(x!=fa[tp]) printf("%d ",x),x=fa[x];putchar('\n');return;
}
inline bool ok(int o){return o>2&&o%3;}
bool bac[4];
bool pd[N];
signed main(){#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);
#endifmemset(fi,-1,sizeof(fi));cnt=-1;n=read();m=read();k=read();for(int i=1;i<=m;i++){int x=read(),y=read();addline(x,y);addline(y,x);}dfs(1,0);for(int i=1;i<=n;i++){if(1ll*dep[i]*k>=n){printf("PATH\n");printf("%d\n",dep[i]);print(i,1);return 0;}}printf("CYCLES\n");for(int i=1;i<=n&&k;i++){int x(0),y(0),z(0);bac[0]=bac[1]=bac[2]=0;if(jd[i]) continue;for(auto now:v[i]){if(pd[now]) continue;if(ok(dep[i]-dep[now]+1)){printf("%d\n",dep[i]-dep[now]+1);pd[i]=1;print(i,now);k--;break;}else if(x&&ok(abs(dep[x]-dep[now])+1+1)){if(dep[x]>dep[now]) swap(x,now);printf("%d\n%d ",dep[now]-dep[x]+1+1,i);print(now,x);pd[i]=1;k--;break;}else if(y&&ok(abs(dep[y]-dep[now])+1+1)){if(dep[y]>dep[now]) swap(y,now);printf("%d\n%d ",dep[now]-dep[y]+1+1,i);print(now,y);pd[i]=1;k--;break;}else if(z&&ok(abs(dep[z]-dep[now])+1+1)){if(dep[z]>dep[now]) swap(z,now);printf("%d\n%d ",dep[now]-dep[z]+1+1,i);print(now,z);pd[i]=1;k--;break;}if(!bac[dep[now]%3]){bac[dep[now]%3]=1;if(!x) x=now;else if(!y) y=now;else if(!z) z=now;}}}return 0;
}
/**/

CF1103D Professional layer

Description\text{Description}Description

给定 1≤n≤1061 \le n \le 10^61≤n≤106 个正整数 ai,1≤ai≤1012a_i,1 \le a_i≤10^{12}ai​,1≤ai​≤1012,以及正整数 1≤k≤10121 \le k \le 10^{12}1≤k≤1012,修改第 iii 个正整数 aia_iai​ 的花费为 ei,1≤ei≤109e_i,1 \le e_i \le 10^9ei​,1≤ei​≤109 。

要求选出若干个正整数进行一次修改,使得修改后所有正整数的最大公约数等于 111 。修改操作为:对于正整数 aaa,选择 aaa 的一个约数 d≤kd \le kd≤k,把 aaa 修改为 $ \frac{a}{d}$。

设选出并修改的正整数有 xxx 个,他们的花费之和为 yyy,则总的修改花费为 x×yx \times yx×y。求最小花费。

Solution\text{Solution}Solution

毒瘤状压题。
不难想到,公因数的质因子不超过 111111 个,可以状压。
关键就是对复杂度的优化。
(以下设质因子个数为 kkk)
朴素 dp 的复杂度是 O(nk3k)O(nk3^k)O(nk3k),难以通过。
考虑优化。
首先,注意到会有大量的重复数(打表可知不同的数只有 10410^4104 个),每种数字取代价最小的前 kkk 个即可。
然后,数的数里降到了十万级别,我们可以暴力求出每个数可以转移到那些质因数集合,而每个集合其实也只需要取前 kkk 个数进行转移,所以转移数降到了 k×2kk\times2^kk×2k。
对每个转移集合的补集枚举子集转移,再加上枚举一维选取个数的复杂度,总复杂度 3k×k23^k\times k^23k×k2。
注意每次不能暴力更新滚动数组,复杂度会假掉,所以需要开个 vector 记录一下更新了哪些状态。
注意开 longlong。

Code\text{Code}Code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define debug(...) fprintf(stderr,__VA_ARGS__)
const int N=2e6+100;
inline ll read(){ll x(0),f(1);char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c)) {x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}
int n,m;
ll k,flag;
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
struct node{ll a,c;
}p0[N],p[N];
bool cmpc(node x,node y){return x.c<y.c;}
bool cmpa(node x,node y){return x.a<y.a;}
ll tot,g;
ll dp[2][13][2105],now,nxt;
ll prime[13],cnt;
map<ll,int>mp;
vector<int>v[2105];
ll w[13],mi[13],bit[2105];
vector<int>vv[N];
void findtrans(int id){ll x=p[id].a;//ll x=p[i].a;for(int j=1;j<=cnt;j++){w[j]=1;while(x%prime[j]==0){x/=prime[j];w[j]*=prime[j];}}for(int s=0;s<(1<<cnt);s++){ll o=1;int ss=s;if((int)v[s].size()==cnt) continue;while(ss){o*=w[bit[ss&-ss]+1];ss-=ss&-ss;}if(o<=k){//v.push_back(s);v[s].push_back(id);//printf("  s=%d o=%lld\n",s,o);}}
}
void init(){int tp=floor(sqrt(g));for(int i=2;i<=tp;i++){if(g%i==0){prime[++cnt]=i;while(g%i==0) g/=i;}}if(g>1) prime[++cnt]=g;sort(p0+1,p0+1+n,cmpc);for(int i=1;i<=n;i++){int x=p0[i].a;if(mp.find(x)!=mp.end()&&mp[x]>=cnt) continue;p[++tot]=p0[i];mp[x]=mp[x]+1;/*for(int j=1;j<=cnt;j++){if(x%prime[j]==0){p[++tot]=p0[i];mp[x]=mp[x]+1;break;}}*/}mi[0]=1;bit[1]=0;for(int i=1;i<=cnt;i++) mi[i]=mi[i-1]<<1,bit[mi[i]]=i;for(int i=1;i<=tot;i++) findtrans(i);//sort(p+1,p+1+tot,cmpa);for(int i=0;i<(1<<cnt);i++){for(auto x:v[i]) vv[x].push_back(i);}
}
vector<int>tr;
void DP(){memset(dp,0x3f,sizeof(dp));dp[now=1][0][0]=0;for(int i=1;i<=tot;i++){//swap(nxt,now);tr.clear();for(auto ns:vv[i]){int t=((1<<cnt)-1)^ns,T=t;//debug("ns=%d\n",ns);dp[nxt][1][ns]=min(dp[nxt][1][ns],p[i].c);tr.push_back(ns);for(;t;t=T&(t-1)){tr.push_back(t|ns);for(int o=0;o<cnt;o++){//debug("ns=%d t=%d o=%d\n",ns,t,o);dp[nxt][o+1][t|ns]=min(dp[nxt][o+1][t|ns],dp[now][o][t]+p[i].c);}}}for(auto s:tr){for(int o=0;o<=cnt;o++) dp[now][o][s]=min(dp[now][o][s],dp[nxt][o][s]);}/*for(int s=0;s<(1<<cnt);s++){for(int o=0;o<=cnt;o++){dp[nxt][o][s]=min(dp[nxt][o][s],dp[now][o][s]);//if(dp[nxt][o][s]<1e9) printf("s=%d num=%d dp=%lld\n",s,o,dp[nxt][o][s]);} }*/}
}
void findans(){ll ans(2e18),op;for(int i=0;i<=cnt;i++){if(dp[now][i][(1<<cnt)-1]<1e18){if(ans>dp[now][i][(1<<cnt)-1]*i) op=i;ans=min(ans,dp[now][i][(1<<cnt)-1]*i);}}printf("%lld\n",ans>1e18?-1:ans);//if(flag) printf("g=%lld op=%lld tot=%lld\n",g,op,tot);//debug("ans=%lld num=%lld\n",ans,op);
}
signed main(){#ifndef ONLINE_JUDGEfreopen("a.in","r",stdin);freopen("a.out","w",stdout);
#endifn=read();k=read();for(int i=1;i<=n;i++) p0[i].a=read(),g=gcd(g,p0[i].a);for(int i=1;i<=n;i++) p0[i].c=read();//printf("g=%lld\n",g);flag=p0[1].a==204367626045ll;init();//debug("ok\n");DP();findans();return 0;
}
/**/

CodeForces:1103(div1)1104(div2)相关推荐

  1. CodeForces:103(div1)104(div2)

    文章目录 前言 CF104A Blackjack Description\text{Description}Description Solution\text{Solution}Solution Co ...

  2. CodeForces:372(div1)div373(div2)

    文章目录 前言 CF373A Collecting Beats is Fun Description\text{Description}Description Solution\text{Soluti ...

  3. CodeForces:749(div1)750(div2)

    文章目录 前言 CF450A Jzzhu and Children Description\text{Description}Description Solution\text{Solution}So ...

  4. CodeForces: 360(div1)361(div2)

    文章目录 前言 CF361A Levko and Table Description\text{Description}Description Solution\text{Solution}Solut ...

  5. codeforces:1361(div1)1362(div2):总结

    文章目录 前言 1362-A. Johnny and Ancient Computer 解析 1362-B - Johnny and His Hobbies 解析 1362-C - Johnny an ...

  6. 【Codeforces #167 Div1 Div2】Solutions

    [A. Dima and Friends] http://www.codeforces.com/contest/272/problem/A 题目大意:n+1个人出手指头,加起来再做类似约瑟夫的出圈,问 ...

  7. css鼠标经过div1时div2消失,CSS_两个div叠加触发事件发生闪烁问题的解决方法,当鼠标移到div1上的时候,会出 - phpStudy...

    两个div叠加触发事件发生闪烁问题的解决方法 当鼠标移到div1上的时候,会出现div2.出现时div2在div1的上面,div2在出现后发生闪烁的问题. 于是开始找问题根源,发现原来是因为当我们触发 ...

  8. 【Codeforces Round #614(div2)】E-Xenon's Attack on the Gangs(树形dp)

    一.题目链接 https://codeforces.com/contest/1293/problem/E 二.题意 给n个结点,n-1条无向边.即一棵树.我们需要给这n-1条边赋上0~n-2不重复的值 ...

  9. codeforces #310 div1 C

    操作无论是U还是L,都会使原图形分裂成两个图形,且两个图形的操作互不影响 我们又发现由于操作点只可能在下斜线上,如果将操作按x排序 那么无论是U还是L,都会将操作序列完整分割成两半,且两个操作序列互不 ...

最新文章

  1. codeblocks使用指南
  2. pandas获取数据行号,删除行数据
  3. Quartz简单触发
  4. java jsoup html_使用JAVA中的JSOUP从HTML中提取CSS样式
  5. [系统安全] 四十一.APT系列(6)Python解析PE文件并获取时间戳判断来源区域
  6. 使用Spock 1.2简化对遗留应用程序的集成测试
  7. python实现qq登录界面_使用Python编写一个QQ办公版的图形登录界面!
  8. 理论基础 —— 查找 —— 插值查找
  9. gulp怎么运行html文件,如果gulp-watch监视html文件,它会运行所有任务
  10. MyBatis逆向工程生成代码(附源码)
  11. 颜色对照表(五)(16进制、RGB、CMYK、HSV、中英文名)
  12. 福师电子计算机主要以,福师《计算机应用基础》在线作业(6) 参考资料
  13. 《沉思录卷一》闪耀在私人生活圈的品质
  14. 一个例子说明贝叶斯定理
  15. 手把手教你ssm整合 超级详细
  16. Docker六大优势,云中部署模式、以及视频demo
  17. 高德地图路径轨迹起点标点不变_竞品分析之高德地图与百度地图
  18. android 麦克风录音输出
  19. 亲身经历的 noshow 与 goshow
  20. js将数字金额转换为大写人民币

热门文章

  1. 干货|MIT线性代数课程精细笔记[第二课]
  2. wince导航_宁可用手机导航,也不用汽车导航?
  3. python小甲鱼爬虫妹子_【Python学习日记】B站小甲鱼:爬虫
  4. a标签传参接收_[pyecharts1.8] 系列配置之标签设置
  5. 超详细图解!【MySQL进阶篇】存储过程,视图,索引,函数,触发器
  6. 查看服务器物理内存大小,如何看服务器的物理内存大小
  7. pandownload 卢本伟_PanDownload复活了!60MB/s!附下载地址
  8. leetcode37. 解数独
  9. 7-1 装载问题 (10 分)(思路+详解)
  10. git did not exit cleanly(解决办法)