A pigofzhou的巧克力棒
二进制拆分。
2^k对应开心值为2^k - 1。
代码写烦了。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#define LL long long
using namespace std;
map<int,int> mp;
void print(){
mp.clear();
int num=1,key=0;
while(num<=1000000000){
mp[num]=key;
num*=2;
key=key*2+1;
}
}
int main(){
int T;
print();
cin>>T;
while(T--){
int n;
scanf("%d",&n);
int t=1;
while(t<=n) t*=2; t=t/2;
//cout<<mp[2]<<" "<<mp[4]<<endl;
int ans=0;
while(n>1){
if(n>=t){
n-=t;
ans+=(mp[t]);
//cout<<t<<" "<<mp[t]<<endl;
t/=2;
}
else{
t/=2;
}
if(t==0||t==1) break;
}
printf("%d\n",ans);
}
return 0;
}
B: Zhazhahe究竟有多二
求N! 中 2的因子个数。
ans=⌊n2⌋+⌊n22⌋+⌊n23⌋+...+⌊n2k⌋
#include <cstdio>
#include <iostream>
#include <cstring>
#define LL long long
using namespace std;
int main(){
int T;
cin>>T;
while(T--){
LL n;
scanf("%lld",&n);
LL ans=0;
LL p=2;
while(p<=n){
ans += n/p;
p*=2;
//cout<<p<<endl;
}
printf("%lld\n",ans);
}
return 0;
}
C: 剁手女生节
枚举。
#include <cstdio>
#include <iostream>
#include <cstring>
#include <climits>
#define LL long long
using namespace std;
int main(){
int T;
cin>>T;
LL n,a,b,c;
while(T--){
scanf("%lld%lld%lld%lld",&n,&a,&b,&c);
int tmp = 4 - (n%4);
if(tmp==4){
puts("0");
continue;
}
if(tmp==1){
LL mn=INT_MAX;
if(mn>a) mn=a;
if(mn>(b+c)) mn=b+c;
if(mn>(c+c+c)) mn=c+c+c;
printf("%lld\n",mn);
}
if(tmp==2){
LL mn=INT_MAX;
if(mn>b) mn=b;
if(mn>(a+a)) mn=a+a;
if(mn>(c+c)) mn=c+c;
printf("%lld\n",mn);
}
if(tmp==3){
LL mn=INT_MAX;
if(mn>c) mn=c;
if(mn>(a+a+a)) mn=a+a+a;
if(mn>(a+b)) mn=a+b;
if(mn>(a+b+b+b)) mn=a+b+b+b;
printf("%lld\n",mn);
}
}
return 0;
}
D:勤奋的涟漪2
首先,f4(0)=−24
然后,13或者12可以呼唤去掉休息日。
#include <cstdio>
#include <iostream>
using namespace std;
int a[200];
int main(){
int T,n;
scanf("%d",&T);
while (T--){
scanf("%d",&n);
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
int ans=0;
for (int i=1;i<=n;i++){
if (a[i]==0) ans++;
if (a[i]==3&&i>1){
if (a[i-1]==1) a[i]=2;
if (a[i-1]==2) a[i]=1;
}
if (a[i]==3&&i==1){
if (a[i+1]==1) a[i]=2;
if (a[i+1]==2) a[i]=1;
}
if (a[i]==a[i-1]&&a[i]!=0&&a[i]!=3){
a[i]=0;
ans++;
}
}
printf("%d\n",-24*ans);
}
}
E:什么排序。。
如果前面的最大值都小于后面的最小值,这就是一个分割点。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <climits>
using namespace std;
int num[1111111];
int f[1111111];
struct node{
int x,id;
}a[1111111];
bool cmp(node a,node b){
if(a.x==b.x){
return a.id<b.id;
}
return a.x<b.x;
}
int main(){
freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
int T,n;
cin>>T;
while(T--){
memset(f,0,sizeof(f));
memset(num,0,sizeof(num));
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d",&num[i]);
for(int i=1;i<=n;i++){
a[i].x=num[i];
a[i].id=i;
}
sort(a+1,a+1+n,cmp);
for(int i=1;i<=n;i++)num[a[i].id]=i;
f[n]=num[n];
for(int i=n-1;i>=1;i--){
f[i]=num[i];
f[i]=min(f[i],f[i+1]);
}
int ans=1,mx=-INT_MAX;
for(int i=1;i<=n;i++){
mx=max(mx,num[i]);
if(f[i+1]>=mx) ans++;
}
printf("%d\n",ans);
if(T!=0)puts("");
}
return 0;
}
F:神偷TMK
puts("ab");
G:神偷TMK后续
求Ckn
#include <cstdio>
#include <cstring>
#define LL long long
LL f[100][100];
int main(){
f[0][0]=1;
f[1][0]=1;f[1][1]=1;
for(int i=2;i<=11;i++)
for(int j=0;j<=i;j++) f[i][j]=f[i-1][j-1]+f[i-1][j];
int n,k;
while(~scanf("%d%d",&n,&k)){
printf("%lld\n",f[n][k]);
}
return 0;
}
H《为什么会变成这样呢》
这里是链接
Single number 问题,其他数都出现了k(k>1)次,只有一个数出现了一次,求这个数。
考虑把出现了多次数消掉,如果k是偶数,则可用异或法;如果k是奇数,则可以用求和再求余法,出现k次的数模k为0,和里最终剩下的是那个single number %k,还是不行,再利用一个性质,小于k的数对k取模就是这个数本身,分别求single number的每一位
#include <iostream>
#include <cstdio>
using namespace std;
unsigned long long FindFirstBitIs1 (long long num){
long long indexBit = 0;
while ((num & 1) == 0 && indexBit < 32){
num >>= 1;
++indexBit;
}
return indexBit;
}
long long IsBit1 (long long data, unsigned long long indexof1){
data >>= indexof1;
return data & 1;
}
void FindNumsAppearOnce (long long data[], long long n, long long &num1, long long &num2){
long long result = 0;
long long i;
for (i=0; i<n; ++i){
result ^= data[i];
}
unsigned long long indexof1 = FindFirstBitIs1 (result);
num1 = 0;
num2 = 0;
for (i=0; i<n; ++i){
if (IsBit1 (data[i], indexof1))
num1 ^= data[i];
else
num2 ^= data[i];
}
}
int main(){
int T;
cin>>T;
while(T--){
long long num1 = 0,num2 = 0;
long long n;
scanf("%lld",&n);
long long *a=new long long[n];
for(long long i=0;i<n;i++){
scanf("%lld",&a[i]);
}
FindNumsAppearOnce(a,n,num1,num2);
printf("%lld %lld\n",min(num1,num2),max(num1,num2));
delete[] a;
}
return 0;
}
I: 只会做水题的jiakin
很烦,但只要理顺就好了。
#include <cstdio>
#include <iostream>
#include <climits>
#include <cstring>
using namespace std;
struct node{
int x,y;
}g[1111][1111];
bool f[1111][1111];
int main(){
freopen("input.txt","r",stdin);
int T,n,m;
scanf("%d\n",&T);
for(int cnt=1;cnt<=T;cnt++){
scanf("%d %d\n",&n,&m);
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++)scanf("(%d,%d)",&g[i][j].x,&g[i][j].y);
getchar();
}
memset(f,0,sizeof f);
f[1][1]=1;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
if(i==1&&j==1) continue;
if(g[i][j].x==2&&g[i][j].y==4){ //2 4
f[i][j]=0;
continue;
}
if(g[i][j].x==2&&g[i][j].y==5){//2 5
f[i][j]=0;
continue;
}
if(g[i][j].x==2&&g[i][j].y==0&&
((g[i][j-1].x==2&&g[i][j-1].y==3)
||(g[i][j-1].x==3&&g[i][j-1].y==0)
||(g[i][j-1].x==3&&g[i][j-1].y==2)
||(g[i][j-1].x==3&&g[i][j-1].y==3)
||(g[i][j-1].x==4&&g[i][j-1].y==0))) f[i][j]=f[i][j-1]; //(2,0)
if(g[i][j].x==2&&g[i][j].y==1&&
((g[i-1][j].x==2&&g[i-1][j].y==2)
||(g[i-1][j].x==3&&g[i-1][j].y==0)
||(g[i-1][j].x==2&&g[i-1][j].y==1)
||(g[i-1][j].x==3&&g[i-1][j].y==1)
||(g[i-1][j].x==4&&g[i-1][j].y==0)
||(g[i-1][j].x==3&&g[i-1][j].y==3))) f[i][j]=f[i-1][j]; //(2,1)
if(g[i][j].x==2&&g[i][j].y==2&&
((g[i][j-1].x==2&&g[i][j-1].y==3)
||(g[i][j-1].x==3&&g[i][j-1].y==0)
||(g[i][j-1].x==3&&g[i][j-1].y==2)
||(g[i][j-1].x==3&&g[i][j-1].y==3)
||(g[i][j-1].x==4&&g[i][j-1].y==0))) f[i][j]=f[i][j-1]; //(2,2)
if(g[i][j].x==2&&g[i][j].y==3&&
((g[i-1][j].x==2&&g[i-1][j].y==2)
||(g[i-1][j].x==3&&g[i-1][j].y==0)
||(g[i-1][j].x==2&&g[i-1][j].y==1)
||(g[i-1][j].x==3&&g[i-1][j].y==1)
||(g[i-1][j].x==4&&g[i-1][j].y==0)
||(g[i-1][j].x==3&&g[i-1][j].y==3))) f[i][j]=f[i-1][j]; //(2,3)
if(g[i][j].x==3&&g[i][j].y==0&&
((g[i][j-1].x==2&&g[i][j-1].y==3)
||(g[i][j-1].x==3&&g[i][j-1].y==0)
||(g[i][j-1].x==3&&g[i][j-1].y==2)
||(g[i][j-1].x==3&&g[i][j-1].y==3)
||(g[i][j-1].x==4&&g[i][j-1].y==0))) f[i][j]=f[i][j-1]; //(3,0)
if(g[i][j].x==3&&g[i][j].y==3&&
((g[i-1][j].x==2&&g[i-1][j].y==2)
||(g[i-1][j].x==3&&g[i-1][j].y==0)
||(g[i-1][j].x==2&&g[i-1][j].y==1)
||(g[i-1][j].x==3&&g[i-1][j].y==1)
||(g[i-1][j].x==4&&g[i-1][j].y==0)
||(g[i-1][j].x==3&&g[i-1][j].y==3))) f[i][j]=f[i-1][j]; //(3,3)
if(g[i][j].x==3&&g[i][j].y==1){
if((g[i-1][j].x==2&&g[i-1][j].y==2)
||(g[i-1][j].x==3&&g[i-1][j].y==0)
||(g[i-1][j].x==2&&g[i-1][j].y==1)
||(g[i-1][j].x==3&&g[i-1][j].y==1)
||(g[i-1][j].x==4&&g[i-1][j].y==0)
||(g[i-1][j].x==3&&g[i-1][j].y==3)) f[i][j]=f[i-1][j];
if(f[i][j]) continue;
if((g[i][j-1].x==2&&g[i][j-1].y==3)
||(g[i][j-1].x==3&&g[i][j-1].y==0)
||(g[i][j-1].x==3&&g[i][j-1].y==2)
||(g[i][j-1].x==3&&g[i][j-1].y==3)
||(g[i][j-1].x==4&&g[i][j-1].y==0)) f[i][j]=f[i][j-1];
}
if(g[i][j].x==3&&g[i][j].y==2){
if((g[i-1][j].x==2&&g[i-1][j].y==2)
||(g[i-1][j].x==3&&g[i-1][j].y==0)
||(g[i-1][j].x==2&&g[i-1][j].y==1)
||(g[i-1][j].x==3&&g[i-1][j].y==1)
||(g[i-1][j].x==4&&g[i-1][j].y==0)
||(g[i-1][j].x==3&&g[i-1][j].y==3)) f[i][j]=f[i-1][j];
if(f[i][j]) continue;
if((g[i][j-1].x==2&&g[i][j-1].y==3)
||(g[i][j-1].x==3&&g[i][j-1].y==0)
||(g[i][j-1].x==3&&g[i][j-1].y==2)
||(g[i][j-1].x==3&&g[i][j-1].y==3)
||(g[i][j-1].x==4&&g[i][j-1].y==0)) f[i][j]=f[i][j-1];
}
if(g[i][j].x==4&&g[i][j].y==0){
if((g[i-1][j].x==2&&g[i-1][j].y==2)
||(g[i-1][j].x==3&&g[i-1][j].y==0)
||(g[i-1][j].x==2&&g[i-1][j].y==1)
||(g[i-1][j].x==3&&g[i-1][j].y==1)
||(g[i-1][j].x==4&&g[i-1][j].y==0)
||(g[i-1][j].x==3&&g[i-1][j].y==3)) f[i][j]=f[i-1][j];
if(f[i][j]) continue;
if((g[i][j-1].x==2&&g[i][j-1].y==3)
||(g[i][j-1].x==3&&g[i][j-1].y==0)
||(g[i][j-1].x==3&&g[i][j-1].y==2)
||(g[i][j-1].x==3&&g[i][j-1].y==3)
||(g[i][j-1].x==4&&g[i][j-1].y==0)) f[i][j]=f[i][j-1];
}
}
if(f[n][m]){
printf("Case %d:\n",cnt);
puts("Well done!");
}
else{
printf("Case %d:\n",cnt);
puts("What a pity!");
}
}
return 0;
}
J: 质方数
打表题。
#include <cstdio>
#include <cstring>
#include <climits>
#include <iostream>
#include <cmath>
using namespace std;
int prime[20001];
int isprime(int x){
for(int i=2;i*i<=x;i++)
if(x%i==0) return 0;
return 1;
}
int main(){
for(int i=2;i<=20001;i++)
if(isprime(i)) prime[++prime[0]]=i;
int T;
scanf("%d",&T);
while(T--){
int n,ans;
scanf("%d",&n);
int mn=INT_MAX;
for(int i=1;i<=prime[i];i++)
if(mn>abs(prime[i]*prime[i]-n)){
mn = abs(prime[i]*prime[i]-n);
ans = prime[i]*prime[i];
}
printf("%d\n",ans);
}
return 0;
}