Codeforces805
A.Fake NP
题意:给定两个整数L R,求[L,R]中公因子不为1的数的最大个数。
题解:显然要想数量尽量多,公因子就不会很大,所以枚举公因子(素数)即可,注意特判L==R的情况
代码:
#include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; const int P[]={2,3,5,7,11,13,17,23,29,0}; int L,R,X,S; int main(){ cin >> L >> R; if(L==R){ cout << L << endl; return 0; } for(int i=0,c;P[i];i++){ c=(R-L)/P[i]; if(L%P[i]==0) c++; if(c>S) S=c,X=P[i]; } cout << X << endl; return 0; }
B.3-palindrome
题意:给定N,求长度为N,仅由a b c构成,不含长度为3的回文子串,含最少c的字符串。
题解:显然由aabb为循环节的字符串符合条件
代码:
#include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; int N; int main(){ cin >> N; for(int i=1;i<=N;i++){ if(i%4==1 || i%4==2) cout << 'a'; else cout << 'b'; } cout << endl; return 0; }
C.Find Amir
题意:有N个节点标号1-N,连接两个节点的花费为(i+j)%(N+1),求所有节点联通的最小花费。
题解:显然i与N-i+1要相连,除此之外的节点连接都会产生花费,显然i与N-i+2相连可以将两“对”联系起来,注意特判N为1的情况。
代码:
#include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; int N; int main(){ cin >> N; if(N<=2){ cout << 0 << endl; return 0; } cout << (N/2-1)+N%2 << endl; return 0; }
D.Minimum number of steps
题意:给定一个仅由a b构成的字符串,每次可将一个字串'ab'变为'bba',求字符串中不含'ab'所需要的操作次数。
题解:显然最后的字符串为b……ba……a的形式,注意到对于一个位置,后面的字母并不会对前面的答案产生影响,注意到b……ba……ab变为合法的话,仅与b之前有多少个a有关,且操作次数为2^(a的数量)-1。
代码:
#include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; #define ll long long const ll P=1e9+7; const int MAXL=1000000+2; ll C,Ans; char S[MAXL]; ll QuickPow(ll a,ll b){ ll t=(b&1?a:1); while(b>>=1){ a=a*a%P; if(b&1) t=t*a%P; } return t; } int main(){ cin >> S; for(int i=0;S[i];i++) if(S[i]=='a') C++; else Ans=(Ans+QuickPow(2,C)-1+P)%P; cout << Ans << endl; return 0; }
E.Ice cream coloring
题意:给定一颗树,树的每个节点有一个点权集,另给一个图,图中两点i j相连当且仅当树中某个节点的点权集同时含i j,求将图染成:相邻两点颜色不同,所需要的最小花费。(保证一个值在树上构成一个联通的子图)
题解:注意到最后的保证,那么我们得到的图实际上是许多联通块连在一起,因此在一个联通块内可以从头标号(在不与相连节点的标号冲突的前提下)。
代码:
#include <queue> #include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; const int MAXN=300000+2; struct HASH{ int u; HASH *next; HASH(){} HASH(int _u,HASH *_next):u(_u),next(_next){} }*tab[MAXN],*rec[2][MAXN],mem[3*MAXN]; int N,M,C,Ans=1,c[MAXN]; queue<int> q[MAXN]; void DFS(int x,int f){ int t=1; for(HASH *p=rec[0][x];p;p=p->next){ if(!c[p->u]){ if(!q[x].empty() && t==q[x].front()) q[x].pop(),t++; c[p->u]=t; for(HASH *r=rec[1][p->u];r;r=r->next) q[r->u].push(t); } } for(HASH *p=tab[x];p;p=p->next) if(p->u!=f) DFS(p->u,x); } int main(){ cin >> N >> M; for(int i=1,s;i<=N;i++){ cin >> s,Ans=max(Ans,s); for(int j=1,x;j<=s;j++){ cin >> x; rec[0][i]=&(mem[C++]=HASH(x,rec[0][i])); rec[1][x]=&(mem[C++]=HASH(i,rec[1][x])); } } for(int i=1,u,v;i<N;i++){ cin >> u >> v; tab[u]=&(mem[C++]=HASH(v,tab[u])); tab[v]=&(mem[C++]=HASH(u,tab[v])); } DFS(1,0); cout << Ans << endl; for(int i=1;i<=M;i++) cout << (c[i]?c[i]:1) << " "; cout << endl; return 0; }
F.Expected diameter of a tree
(待补)