【Codeforces】【#295】【Div.2】
o(︶︿︶)o 唉跪烂了……
B题由于考虑的不周全WA了3次……
C题由于#include了<cmath>,而我函数声明的是pow(LL a,LL b)但调用的时候 【没!有!把!n!的!数据类型!!改成!long long !!!】所以触发了自动类型转换……就调用成cmath库里的了!!!
教训:
以后自己写函数名的时候尽量避开pow等敏感词(NOIP时候的pipe事件……)可以首字母大写,或者改个名字比如pow_mod
A:
统计题……考你会不会C++(或其他语言……)
统计一下是否26个英文字母都出现了即可,大小写均可。(妈蛋考试的时候Dev-C++突然崩溃了,害我还得重启电脑,没本机跑过一遍不敢交啊……万一CE就是50分QAQ)
1 //CF #295 div.2 A 2 #include<cmath> 3 #include<vector> 4 #include<cstdio> 5 #include<cstring> 6 #include<cstdlib> 7 #include<iostream> 8 #include<algorithm> 9 #define rep(i,n) for(int i=0;i<n;++i) 10 #define F(i,j,n) for(int i=j;i<=n;++i) 11 #define D(i,j,n) for(int i=j;i>=n;--i) 12 using namespace std; 13 int getint(){ 14 int v=0,sign=1; char ch=getchar(); 15 while(!isdigit(ch)) {if(ch=='-') sign=-1; ch=getchar();} 16 while(isdigit(ch)) {v=v*10+ch-'0'; ch=getchar();} 17 return v*sign; 18 } 19 const double eps=1e-8; 20 typedef long long LL; 21 /*******************template********************/ 22 bool a[1000]; 23 char s[1000]; 24 25 int main(){ 26 27 int n=getint(); 28 scanf("%s",s); 29 rep(i,n) 30 if (s[i]>='A' && s[i]<='Z') a[s[i]-'A']=1; 31 else a[s[i]-'a']=1; 32 bool sign=1; 33 rep(i,26) 34 if (!a[i]) sign=0; 35 puts(sign ? "YES" : "NO"); 36 return 0; 37 }
B:
1.当n>=m时明显*2是无意义的……ans=n-m;
2.当n<m时,一个简单的过程是这样的:n不断翻倍直到n>=m,然后再不断-1直到n==m; 即 $ n*2^{t_1}-1*{t_3} $
那么怎样操作数就减少了呢?在不断$*2$的过程中插入-1操作!也就是说我们的操作可以写成: $ n*2*2\cdots *2 $ 然后又在中间某些位置插入了-1!
那么我们乘法分配律展开一下就变成了 \[ n*2^{t_1} -1*2^{x_1}-1*2^{x_2}-\dots-1*2^{x_n} (其中2^{x_1}+2^{x_2}+ \dots +2^{x_n}=t_3) \]
看上去好像只要将t3进行二进制拆分,相对应的就是一种合法方案了。真的是这样吗?当t3比较大、而t1比较小的时候呢?$2^{x1}$这项前面的系数就不一定是-1了!因为没有更高位可以进位了!
所以应该是用除法!再取余来分解!
1 //CF #295 div.2 B 2 #include<cmath> 3 #include<vector> 4 #include<cstdio> 5 #include<cstring> 6 #include<cstdlib> 7 #include<iostream> 8 #include<algorithm> 9 #define rep(i,n) for(int i=0;i<n;++i) 10 #define F(i,j,n) for(int i=j;i<=n;++i) 11 #define D(i,j,n) for(int i=j;i>=n;--i) 12 #define pb push_back 13 using namespace std; 14 int getint(){ 15 int v=0,sign=1; char ch=getchar(); 16 while(!isdigit(ch)) {if(ch=='-') sign=-1; ch=getchar();} 17 while(isdigit(ch)) {v=v*10+ch-'0'; ch=getchar();} 18 return v*sign; 19 } 20 const int N=1e7+10,INF=~0u>>2; 21 const double eps=1e-8; 22 typedef long long LL; 23 /*******************template********************/ 24 int n,m,ans; 25 int main(){ 26 n=getint(); 27 m=getint(); 28 ans=1000000; 29 if (m<=n) ans=n-m; 30 else { 31 int t1=0; 32 for(;n<m;n<<=1,t1++); 33 int t2=n-m,t3=1; 34 F(i,1,t1) t3<<=1; 35 while(t2){ 36 t1+=t2/t3; 37 t2%=t3; 38 t3>>=1; 39 } 40 ans=t1; 41 } 42 printf("%d\n",ans); 43 return 0; 44 }
C:
sigh……其实是个傻逼题,我被吓到了所以没敢上手……读懂题目意思后很快就解出来了。
从题目描述中给出的样例可以发现:字符串 s 的每一位都要和字符串 t 的每一位匹配 n 次!也就是说其实每一位是单独考虑的……这一位对那个函数 $ \rho(s,t) $ 的贡献取决于这个字符与原串有多少可以匹配的节点!即它与多少位置的字符相同!显而易见如果要找$\rho$最大的,明显需要让 t 中的字符是 s 中出现次数最多的那个,如果有多个最大值(比如A和G都是出现次数最多的),那每一位都会有两种选择,所以总方案数就是 $x^n\mod P$ 其中x为出现次数最多的字符的种数,n为读入的字符串的长度。
1 //CF #295 div.2 C 2 #include<vector> 3 #include<cstdio> 4 #include<cstring> 5 #include<cstdlib> 6 #include<iostream> 7 #include<algorithm> 8 #define rep(i,n) for(int i=0;i<n;++i) 9 #define F(i,j,n) for(int i=j;i<=n;++i) 10 #define D(i,j,n) for(int i=j;i>=n;--i) 11 #define pb push_back 12 using namespace std; 13 const int N=1e7+10,INF=~0u>>2; 14 const double eps=1e-8; 15 typedef long long LL; 16 /*******************template********************/ 17 const int P=1000000000+7; 18 char s[200010]; 19 int cnt[5]; 20 LL pow(LL a,LL b){ 21 LL r=1,base=a; 22 while(b){ 23 if (b&1) r=r*base%P; 24 base=base*base%P; 25 b>>=1; 26 } 27 return r; 28 } 29 int main(){ 30 int n; 31 cin >>n; 32 scanf("%s",s); 33 memset(cnt,0,sizeof cnt); 34 rep(i,n){ 35 if (s[i]=='A') cnt[1]++; 36 if (s[i]=='T') cnt[2]++; 37 if (s[i]=='C') cnt[3]++; 38 if (s[i]=='G') cnt[4]++; 39 } 40 LL max=-1,ans=-1; 41 F(i,1,4){ 42 if (cnt[i]==max) ans++; 43 else if (cnt[i]>max){ max=cnt[i]; ans=1;} 44 } 45 LL A=pow(ans,n); 46 cout << A <<endl; 47 return 0; 48 }