1. 程式人生 > >CF Week12 作業 解題報告

CF Week12 作業 解題報告

#define 作業 AS swa spa amp def fine ont

611A

題意:給出1<=a<=b<=10^18,求區間[a,b]內有多少個數二進制下只有一個0

solution:2^61>10^18,所以區間內的數最多二進制下61位,位數從2位枚舉到61位,每次把非最高位變成0其余為1,將這個數存到數組裏

 1 #include<iostream>
 2 #include<cstdio>
 3 #define LL long long
 4 using namespace std;
 5 LL A[200000],n;
 6 int main(){
 7     LL a,b; cin>>a>>b;
8 int i,j; 9 for (i=2;i<=61;i++){ 10 LL num=((LL)1<<(LL)i)-1;//位運算註意轉long long 11 for (j=i-2;j>=0;j--){//不能把最高位變成0 12 A[++n]=num^(LL)((LL)1<<(LL)j);//同上 13 } 14 } 15 int pos1=0,pos2=0; 16 for (i=1;i<=n;i++){ 17 if (a<=A[i]&&!pos1) pos1=i;
18 if (b>=A[i]) pos2=i; 19 } 20 cout<<pos2-pos1+1; 21 }

633A

題意:a,b<=100兩種面值硬幣,求能否拼成c<=10000

其實就是求ax+by=c能否求出a,b都為自然數的一組解,用擴歐求出來任意一組,然後運用公式(x+k*b/gcd(a,b),y-k*a/gcd(a,b)),k取任意整數判斷

#include<iostream>
using namespace std;
void Gcd(int a,int b,int &d,int &x,int &y){
    
if (!b){ d=a; x=1; y=0; return; } Gcd(b,a%b,d,y,x); y-=x*(a/b); } int main(){ int a,b,c,gcd,x,y; cin>>a>>b>>c; Gcd(a,b,gcd,x,y); if (c%gcd!=0){cout<<"No"; return 0;}//肯定不會有整數解 x*=c/gcd; y*=c/gcd;//ax+by=c的解 if (x>=0&&y>=0){cout<<"Yes"; return 0;} //兩個解都不為負 int b1=b/gcd,a1=a/gcd; if (x>0) swap(x,y),swap(a1,b1); //將x置為負解 int k=(-x)/b1; if ((-x)%b1!=0) k++; //求出使x+k*b/gcd(a,b)>=0的最小k if (y-k*a1<0) cout<<"No"; //此時另一個解y-k*a/gcd(a,b) else cout<<"Yes"; }

CF Week12 作業 解題報告