zoukankan      html  css  js  c++  java
  • 第二次练习总结

    第二次练习总结

    • 对新手来说 这个题确实有些难了

    AC代码(别照抄)

    A Yes OK

    • 位与 移位 提取整数的指定位
    #include <stdio.h>
    int main(void){
    	int T,n,k;
    	scanf("%d",&T);
    	while(T--){
    		scanf("%d%d",&k,&n);
    		puts(k & (1 << n)?"Yes!":"NO!");
    
    	}
    	return 0;
    }
    

    B 循环移位

    • 注意数据范围 移出去了要有地方能接住
    • 可以用数组模拟(但是不推荐)
    • 可以循环(参考下面某同学的代码)
    #include<stdio.h>
    
    int main(){
    	int N,k,i;
    	unsigned long long a,a1;
    
    	while((scanf("%d%d%llu",&N,&k,&a)) != EOF){
    		k %= N;
    		for(i = 0;i < k;i++){
    			a1 = a;
    			a1 &= 1ll << (N - 1);
    			a <<= 1ll;
    			if(a1 != 0){
    				a |= 1;
    			}
    			a &= (1ll << N) - 1;
    		}
    		printf("%llu
    ",a);
    	}
    	return 0;
    }
    
    • 也可以一行代码秒了这个题(存好模板 循环左移同理 各位可以想下)
    #include <stdio.h>
    #define CROL(X,i,n) ((((X)<<(i))|((X)>>((n)-(i))))&((1ull<<(n))-1ull))
    //可以写上面的宏
    //或者下面的函数
    long long crol_ull(long long a,long long n,long long k){//对n位的二进制数a循环移位k次
    	return ((a << k | (a >> (n - k))) & ((1ll << n) - 1ll));
    }
    int main(){
        unsigned long long n,k,a;
    	while(~scanf("%llu%llu%llu",&n,&k,&a)){
    		k = k % n;
    		printf("%llu
    ",CROL(a,k,n));
    	}
        return 0;
    }
    

    C 复数计算器

    • 复数计算是重点
    • 分类讨论得全面
    • 格式化输出(用不好就得多分类讨论+if-else)
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    double eps = 1e-8;
    int eq(double x,double y){
    	return fabs(x - y) < eps;
    }
    int isint(double x){
    	return fabs(round(x) - x) < eps;
    }
    int main(int argc,char **argv){
    	double a,b,c,d,x = .0,y = .0;
    	char op;
    	while(~scanf("(%lf%lfi)%c(%lf%lfi)
    ",&a,&b,&op,&c,&d)){
    		switch(op){
    		case '+':
    			x = a + c;y = b + d;break;
    		case '-':
    			x = a - c;y = b - d;break;
    		case '*':
    			x = a * c - b * d;y = b * c + a * d;break;
    		case '/':
    			x = (a * c + b * d) / (c * c + d * d);
    			y = (b * c - a * d) / (c * c + d * d);
    			break;
    		}
    		//out:x+iy
    		if(eq(x,0.0)){//real==0
    			if(eq(y,0.0)){//real==0;imag==0
    				puts("0");
    			}
    			else if(eq(y,1.0)){
    				puts("i");
    			}
    			else if(eq(y,-1.0)){
    				puts("-i");
    			}
    			else if(isint(y)){
    				printf("%.0fi
    ",y);
    			}
    			else{
    				printf("%.2fi
    ",y);
    			}
    		}
    		else{//先real再imag
    			if(isint(x)){
    				printf("%.0f",x);
    			}
    			else{
    				printf("%.2f",x);
    			}
    			if(!eq(y,0.0)){
    				if(eq(y,1.0)){
    					printf("+i");
    				}
    				else if(eq(y,-1.0)){
    					printf("-i");
    				}
    				else if(isint(y)){
    					printf("%+.0fi",y);
    				}
    				else{
    					printf("%+.2fi",y);
    				}
    			}
    
    			putchar('
    ');
    		}
    	}
    	return 0;
    }
    

    D 进制回文数

    • cbj进制转换的升级版 思路类似
    • 读进来的是10进制就很舒服(可以思考下如果不是10进制输入该怎么办)
    #include <stdio.h>
    int main(){
    	int radix,num,i = 0,m,n,flag = 1;
    	char buffer[200] = {0};
    	char keys[40] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    	scanf("%d",&radix);
    	while(~scanf("%d",&num)){
    		i = 0;flag = 1;
    		while(num){
    			buffer[i] = keys[(num % radix)];
    			i++;
    			num /= radix;
    		}
    		n = i - 1;
    		for(m = 0;m <= n;m++,n--){//验证回文数
    			if(buffer[m] != buffer[n]){
    				flag = 0;break;
    			}
    		}
    		if(flag){//反着输出
    			while(i--){
    				putchar(buffer[i]);
    			}
    			putchar('
    ');
    		}
    	}
    	return 0;
    }
    

    E 木木枭学高中集合论

    • 枚举,代码填空

    • HINT:如果算法用到了容斥原理,它们的代码主体结构差不多都长成这个样子:

      外层循环跑数,内层循环跑位,然后再加一个右移取位的判断。

    • 注意运算符的优先级 如果不确定可以套一堆括号

    #include<stdio.h>
    int main(){
    	int i,n;
    	scanf("%d",&n);
    	for(i = 0;i < (1 << n);i++){
    		int j;
    		for(j = 0;j < n;j++){
    			if(((i >> j) & 1) == 1)
    				printf("%d",j);
    			else{
    				printf("-");
    			}
    
    		}
    		printf("
    ");
    	}
    	return 0;
    }
    

    F 高低位

    • GCC编译器有__int128_t类型 可以秒了这个题 但是需要自行解决输出输出问题
    • 如果你的电脑上有linux或者win10和最新的gcc for windows那么 赶 紧 存 模 板
    #include <stdio.h>
    void write128(__int128_t a){
        if(a < 0){
            putchar('-');a = -a;
        }
        if(a > 9)write128(a / 10);
        putchar(a % 10 + '0');
    }
    __int128_t read128(){
        __int128_t k = 0,sgn = 1;
        char ch = getchar();
        while(!isdigit(ch)){
            if(ch == '-')sgn = -1;
            ch = getchar();
        }
        while(isdigit(ch)){
            k = (k << 1) + (k << 3) + (ch - '0');
            ch = getchar();
        }
        return k * sgn;
    }
    int main(){
        __int128_t a,b,c,d,sum;
        a = read128();b = read128();c = read128();d = read128();
        a = (a << 64) | b;c = (c << 64) | d;
        sum = a + c;
        if(sum != ((__int128_t)0x8000000000000000 << 64)){
            write128(sum);
        }
        else{
            puts("-170141183460469231731687303715884105728");
        }
        return 0;
    }
    
    • 数组模拟也行 就是有亿点费劲
    #include<stdio.h>
    
    int main(){
    	unsigned long long num1w,num1s,num2w,num2s;
    	int a[128]={0},b[128]={0},c[128]={0};
    	int i=0;
    	int d[128]={0},x[128]={0};
    	int k=0,t=0;
    	int sum=1;
    	scanf("%llu%llu",&num1w,&num1s);
    	scanf("%llu%llu",&num2w,&num2s);
    	while(num1s>0){
    		a[i]=num1s%2;
    		num1s=num1s/2;
    		i++;
    	}
    	i=0;
    	while(num2s>0){
    		b[i]=num2s%2;
    		num2s=num2s/2;
    		i++;
    	}
    	i=64;
    	while(num1w>0){
    		a[i]=num1w%2;
    		num1w=num1w/2;
    		i++;
    	}
    	i=64;
    	while(num2w>0){
    		b[i]=num2w%2;
    		num2w=num2w/2;
    		i++;
    	}
    	for(i=0;i<127;i++){
    		c[i]=c[i]+a[i]+b[i];
    		if(c[i]>=2){
    			c[i]=c[i]-2;
    			c[i+1]=1;
    		}
    	}
    	c[127]=c[127]+a[127]+b[127];
    	if(c[127]==3||c[127]==1){
    		c[127]=1;
    		for(i=0;i<128;i++){
    			if(c[i]==1){
    				c[i]=0;
    			}else{
    				c[i]=1;
    			}
    		}
    		c[0]=c[0]+1;
    		for(i=0;i<128;i++){
    			if(c[i]==2){
    				c[i]=0;
    				c[i+1]+=1;
    			}
    		}
    		printf("-");
    		while(sum>0){
    			i=127;
    			for(i;i>=0;i--){
    				while(t<10){
    					t=(t<<1)+c[i];
    					i--;
    					if(i==-1){
    						break;
    					}
    				}
    				if(i==-1){
    					if(t<10){
    						break;
    					}
    				}
    				i++;
    				d[i]=1;
    				t=t-10;
    			}
    			x[k]=t;
    			t=0;
    			k++;
    			sum=0;
    			for(i=0;i<128;i++){
    				c[i]=d[i];
    				sum+=c[i];
    			}
    			for(i=0;i<128;i++){
    				d[i]=0;
    			}		
    		}
    		for(k=k-1;k>=0;k--){
    			printf("%d",x[k]);
    		}	
    	}else{
    		c[127]=0;
    	}
    	while(sum>0){
    		i=127;
    		for(i;i>=0;i--){
    			while(t<10){
    				t=(t<<1)+c[i];
    				i--;
    				if(i==-1){
    					break;
    				}
    			}
    			if(i==-1){
    				if(t<10){
    					break;
    				}
    			}
    			i++;
    			d[i]=1;
    			t=t-10;
    		}
    		x[k]=t;
    		t=0;
    		k++;
    		sum=0;
    		for(i=0;i<128;i++){
    			c[i]=d[i];
    			sum+=c[i];
    		}
    		for(i=0;i<128;i++){
    			d[i]=0;
    		}	
    	}
    	for(k=k-1;k>=0;k--){
    		printf("%d",x[k]);
    	}
    	return 0;
    }
    

    G CRC16

    • 读取hexadecimal需要在scanf里面使用%x格式控制符 输出也要注意类似问题
    #include <stdio.h>
    #include <stdlib.h>
    int main(){
    	int a,CRC = 0xFFFF,c,d,i,flag;
    	while(scanf("%X",&a) != EOF){
    		CRC = (CRC & (0xff00)) | (((CRC & 0xff) ^ a) & 0xff);
    		for(i = 1;i <= 8;i++){
    			flag = CRC & 1;
    			CRC >>= 1;
    			if(flag){
    				CRC = CRC ^ 0xA001;
    			}
    		}
    		
    	}
    	printf("%02X %02X
    ",(CRC & 0xff),((CRC & 0xff00) >> 8));
    	return 0;
    }
    

    H 传接球

    • 输出N0t 1n my team!别打错了
    #include <stdio.h>
    int main(int argc,char **argv){
    	int n,a,b,f;
    	int team[101] = {0},chuan[101] = {0},jie[101] = {0};
    	scanf("%d",&n);
    	while(n--){
    		scanf("%d%d",&a,&b);
    		if(team[a] == 0){
    			team[a] = 1;
    		}
    		if(team[b] == 0){
    			team[b] = 1;
    		}
    		chuan[a]++;
    		jie[b]++;
    	}
    	scanf("%d",&f);
    	if(team[f]){
    		printf("%d %d
    ",chuan[f],jie[f]);
    	}
    	else{
    		puts("N0t 1n my team!");
    	}
    	return 0;
    }
    

    I 浮点数(1)

    • 照着题意模拟 在纸上比划比划 定好位置会舒服些
    • 位运算可以做
    char s[20] = {0};
    	int k,E,F,bias,i;
    	double f,sgn;
    	scanf("%s",s);
    	while(~scanf("%d",&k))	{
    		E = 0;F = 0;
    		bias = (1 << (k - 1)) - 1.;
    		if(s[0] == '1')sgn = -1.;
    		else sgn = 1;
    		for(i = 0;i < k;i++){
    			if(s[k - i] == '1'){
    				E |= (1 << i);
    			}
    		}
    		for(i = 0;i < 15 - k;i++){
    			if(s[15 - i] == '1'){
    				F |= (1 << i);
    			}
    		}
    		f = 1.0 + ((double)F / (double)(1 << (15 - k)));
    		printf("%.8f
    ",f * pow(2.0,E-bias) * sgn);//这里如果用long long转double会出事 必须用pow
    	}
    

    J 浮点数(2)

    • 思路类似上面的I题
    • 分数化简 我们以前做过类似的 这里直接粘过来 改了改 包装了一个函数
    #include <stdio.h>
    int gcd(int a,int b){
    	return a % b == 0?b:gcd(b,a % b);
    }
    void frac(int m,int n,int sign){
    	//end preprocess m>0 n>0
    	if(m == 0){
    		puts("0");
    		return;
    	}
    	int g = gcd(m,n);
    	int a = m / g;
    	int b = n / g;
    	int res = a / b,mod = a % b;
    	if(res){
    		if(mod){
    			if(sign){
    				printf("-%d-%d/%d
    ",res,mod,b);
    			}
    			else{
    				printf("%d+%d/%d
    ",res,mod,b);
    			}
    		}
    		else{
    			if(sign){
    				putchar('-');
    			}
    			printf("%d
    ",res);
    		}
    	}
    	else{
    		if(mod){
    			if(sign){
    				printf("-%d/%d
    ",mod,b);
    			}
    			else{
    				printf("%d/%d
    ",mod,b);
    			}
    		}
    	}
    }
    int main(){
    	char s[30] = {0};
    	//int m = 16,k = 5,n = 10;
    	int bias = 15;//(1<<(5-1))-1
    	while(~scanf("%s",s)){
    		char se[10] = {0};
    		char sf[20] = {0};
    		int sign = s[0] == '1',i,e = 0,f = 0;
    		strncpy(se,s + 1,5);
    		strncpy(sf,s + 6,10);
    		for(i = 0;i < 5;i++){
    			if(se[5 - i - 1] == '1')e |= (1 << i);
    		}
    		for(i = 0;i < 10;i++){
    			if(sf[10 - i - 1] == '1')f |= (1 << i);
    		}
    		if(e == 31){
    			if(f != 0){
    				puts("NaN");
    				continue;
    			}
    			else{
    				puts(sign?"-inf":"inf");
    				continue;
    			}
    		}
    		else{
    			int a,b;
    			if(e == 0){
    				a = f;
    				b = 1 << 24;
    			}
    			else{
    				a = f + (1 << 10);
    				b = 1 << 10;
    				if(e > bias){
    					a *= (1 << (e - bias));
    				}
    				else{
    					b *= (1 << (bias - e));
    				}
    			}
    			//输出约分后的a/b
    			frac(a,b,sign);
    			memset(s,0,sizeof(s));
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    Ajax XMLHttpRequest对象的三个属性以及open和send方法
    去空格
    绑定事件中 如可控制函数的执行次数
    我之理解---计时器setTimeout 和clearTimeout
    关于border边框重叠颜色设置问题
    YbtOj练习:二分5 飞离地球
    YbtOj练习:二分4 分割矩阵
    YbtOj练习:二分3 攻击法坛
    YbtOj练习:贪心3 最优密码
    YbtOj练习:二分2 最小时间
  • 原文地址:https://www.cnblogs.com/woshilxcdexuesheng/p/14579965.html
Copyright © 2011-2022 走看看