[题解]CF Round #386 (Div.2)
2016-12-20 08:36
183 查看
747A:Display Size
题意简述
给你n,求一对x,y使得x∗y=n并且x,y最接近。数据范围
n≤106思路
从n√开始查找,不要漏1。代码
#include<cstdio> #include<cmath> using namespace std; int n; int main() { scanf("%d",&n); for (int i=int(sqrt(n));i>=1;i--) if (n%i==0) { printf("%d %d",i,n/i); return 0; } return 0; }
747B:Mammoth’s Genome Decoding
题意简述
只含有ATGC?的字符串S,要求用
ATGC替换
?,使得最后
ATCG个数一样多。
数据范围
4≤|S|≤255思路
只有4||S|的时候才有答案。替换每个字符知道个数为|S|4。
代码
#include<cstdio> #include<iostream> using namespace std; int num[100]; int n,mx; char st[1010]; int main() { scanf("%d",&n); scanf("%s",st); for (int i=0;i<n;i++) if (st[i]!='?') { num[st[i]-'A']++; mx=max(mx,num[st[i]-'A']); } if (mx*4>n||n%4!=0) { printf("==="); return 0; } for (int i=0;i<n;i++) if (st[i]=='?') if (num['A'-'A']<n/4) st[i]='A',num['A'-'A']++; else if (num['G'-'A']<n/4) st[i]='G',num['G'-'A']++; else if (num['T'-'A']<n/4) st[i]='T',num['T'-'A']++; else st[i]='C',num['C'-'A']++; printf("%s",st); return 0; }
747C:Servers
题意简述
你有n台服务器,现在有q项工作要安排。每次安排工作,要求找出ki台空闲的编号最小的服务器,工作从ti开始,持续di秒。
每次输出安排的服务器的编号之和,或输出−1表示无法安排。
数据范围
1≤n≤1001≤q≤105
思路
根本不用数据结构维护……直接模拟。
复杂度O(nq)
代码
#include<cstdio> using namespace std; int n,q,t,k,d,now,ans; int hh[110]; int main() { scanf("%d%d",&n,&q); for (int i=1;i<=q;i++) { scanf("%d%d%d",&t,&k,&d); now=0; for (int j=1;j<=n;j++) if (hh[j]<t) now++; if (now<k) { printf("-1\n"); continue; } now=0; ans=0; for (int j=1;j<=n&&now<k;j++) if (hh[j]<t) { now++; ans+=j; hh[j]=t+d-1; } printf("%d\n",ans); } return 0; }
747D:Winter Is Coming
题意简述
连续的n天里,每天的气温为ai。你的汽车有冬季轮胎和夏季轮胎。
夏季轮胎无限制,冬季轮胎最多使用w天。
如果气温≥0则可以使用冬季或夏季轮胎。
如果气温<0则当天必须使用冬季轮胎。
初始你装备了夏季轮胎。
问度过冬天,至少需要更换几次轮胎。
或输出−1表示无解。
数据范围
1≤w≤n≤2∗105−20≤ai≤20
思路
堆,贪心。一开始假设使用冬季轮胎天数最少,每次能换就换。
把所有的气温≥0的段加入堆里。
每次取出一个最短的,如果能不换就不换。
特判一下最后一段,这段对答案的贡献是1。
代码
#include<cstdio> #include<queue> #include<vector> using namespace std; int n,k,cnt,now,ans,hh,fir; int seq[200010]; priority_queue<int,vector<int>,greater<int> > q; int main() { scanf("%d%d",&n,&k); for (int i=1;i<=n;i++) { scanf("%d",&seq[i]); if (seq[i]<0) cnt++; } if (cnt>k) { printf("-1"); return 0; } for (int i=1;i<=n;i++) if (seq[i]<0&&seq[i-1]>=0) ans+=2; for (int i=1;i<=n;i++) if (seq[i]<0) { fir=i; break; } for (int i=fir;i<=n;i++) if (seq[i]>=0&&seq[i-1]<0) now=1; else if (seq[i]>=0) now++; else { if (now) q.push(now); now=0; } hh=cnt; while (!q.empty()) if (hh+q.top()<=k) { hh+=q.top(); q.pop(); ans-=2; } else break; if (hh+now<=k) ans--; printf("%d",ans); return 0; }
747E:Comments
题意简述
给出一个字符串S,描述了一个森林结构。每段有两个成分,第一个成分是一个串,表示了这个节点的内容,下一个成分是子节点数量x,表示后面的x个段都是它的孩子。
问一共有多少层,每层的内容分别是什么,安装dfs序输出。
数据范围
1≤|S|≤106思路
直接dfs即可。代码
#include<cstdio> #include<cstring> #include<vector> using namespace std; struct Node{ int l,r; Node(int _l,int _r) { l=_l,r=_r; } }; char st[1000010]; int len,l,r,deep; vector<Node> ans[1000010]; Node getst(int s) { if (st[s]==',') s++; l=s; for (r=s;st[r]!=','&&r<len;r++); return Node(l,r-1); } int getnum(int s) { if (st[s]==',') s++; l=s; int ret=0; for (r=s;st[r]!=','&&r<len;r++) ret=ret*10+st[r]-'0'; return ret; } void dfs(int de) { deep=max(deep,de); ans[de].push_back(getst(r)); int tmp=getnum(r); while (tmp--) dfs(de+1); } void prt(Node f) { for (int i=f.l;i<=f.r;i++) putchar(st[i]); putchar(' '); } int main() { scanf("%s",st); len=strlen(st); r=0; while (r<len) dfs(1); printf("%d\n",deep); for (int i=1;i<=deep;i++) { for (int j=0;j<ans[i].size();j++) prt(ans[i][j]); puts(""); } return 0; }
747F:Igor and Interesting Numbers
题意简述
问每种数字出现的次数≤t的16进制数中,第k小的是哪个。数据范围
1≤k≤2∗1091≤t≤10
思路
这是到好题。首先安装数位DP的思路,我们需要诸位确定每个数是多少。
那么我们就需要知道f[i][j]表示有i位,最高位为j的数有多少个。
通常我们都是通过预处理来求得这个数组的。
但是本题中,每种数字的个数会随着你之前的决策发生变化,所有预处理的方法行不通。
那么我们就在诸位确定的时候,每次暴力DP统计。
转移我们从小的数字开始放。
f[i][j]=f[i−k][j−1]∗Cki
注意k的枚举上限。
最终f[n][16]就是本次统计答案。
复杂度O(16log2k)
代码
#include<cstdio> #include<iostream> using namespace std; #define m 16 long long c[20][20]; int k,t,deep,a[20]; long long f[20][20]; long long size; void pre() { c[1][0]=c[1][1]=1; for (int i=2;i<=10;i++) { c[i][0]=1; for (int j=1;j<=i;j++) c[i][j]=c[i-1][j]+c[i-1][j-1]; } } long long dp(int x) { for (int i=0;i<=m;i++) f[0][i]=1; for (int i=1;i<=x;i++) for (int j=1;j<=m;j++) { f[i][j]=0; for (int k=0;k<=min(i,a[j]);k++) f[i][j]+=f[i-k][j-1]*c[i][k]; } return f[x][m]; } void prt(int x) { if (x<10) putchar(x+'0'); else putchar(x-10+'a'); } void dfs(int k,int x) { if (x==0) return; for (int i=x==deep ? 2 : 1;i<=m;i++) { if (a[i]==0) continue; a[i]--; size=dp(x-1); if (size>=k) { prt(i-1); dfs(k,x-1); break; } k-=size; a[i]++; } } int main() { scanf("%d%d",&k,&t); pre(); for (int i=1;i<=m;i++) a[i]=t; deep=1; while (1) { a[2]--; size=dp(deep-1)*15; a[2]++; if (size>=k) break; deep++; k-=size; } dfs(k,deep); return 0; }
相关文章推荐
- 喵哈哈村的魔法考试 Round #11 (Div.2) 题解
- CodeForces#285 div.2 题解
- CodeForces #292 div.2 题解
- 喵哈哈村的魔法考试 Round #20 (Div.2) 题解
- Codeforces Round #395 Div.2 题解
- 喵哈哈村的魔法考试 Round #10 (Div.2) 题解
- BestCoder Round #54 (div.2) 题解
- 喵哈哈村的魔法考试 Round #5 (Div.2) 题解
- 喵哈哈村的魔法考试 Round #9 (Div.2) 题解
- 喵哈哈村的魔法考试 Round #18 (Div.2) 题解
- 喵哈哈村的魔法考试 Round #19 (Div.2) 题解
- Tutorial CodeForces Round 289 (Div.2) (Second Winter Computer Camp Selection 2015) 题解
- 【BestCoder Round #81 (div.2)】【HDU5670&5671&5672】题意&题解&代码(C++)
- Codeforces Round 411 Div.2 题解
- 喵哈哈村的魔法考试 Round #1 (Div.2) 题解&源码(A.水+暴力,B.dp+栈)
- [题解]CF Round #385 (Div.2)
- 喵哈哈村的魔法考试 Round #13 (Div.2) 题解
- CodeForces #294 div.2 题解
- 喵哈哈村的魔法考试 Round #1 (Div.2) 题解
- 喵哈哈村的魔法考试 Round #12 (Div.2) 题解