蓝桥杯 算法训练 审美课

蓝桥杯 算法训练 审美课

题目链接:http://lx.lanqiao.cn/problem.page?gpid=T519

思路

1.暴力求解:

题目的时间限制为1s,对于二重循环,n最大可以取到2500,题目中的n最大可取的50000,因此暴力法不能得满分
当代一般计算机一秒运力

2.二进制取反:

用二进制存储的思路如下:

1.将每个学生的答案用数组b[i]以二进制的形式存储。故答案相同的学生数组b[i]存的值是相同的。例如某同学的答案为0101001,则b[i]等于0101001表示的十进制整数41。
2.数组ans[b[i]]用于存储每种答案的人数。例如,假设ans[3]=10,即有10个人答案相同且答案都为3 。
3.按行遍历(此时为一重循环),令MAX=(2 ^ m)-1(此时^表示次方运算,装逼一点的写法是MAX=1<<m-1),对每一行的b[i]取反,可以用b[i] ^MAX(在c++中 ^ 表示异或,简单一点的写法是MAX-b[i] ),与取反后的答案相同的 即为题目要求的完全相反的答案 (例如,m=3,即MAX=7,若b[i]=4,取反后为7-4=3,若ans[3]=10,则所有答案中与4完全不同的有10个。
4.最后sum/2是因为重复计算了,除以2之后才是“有多少对同学”。

代码

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cmath>
#define ll long long
using namespace std;
int ans[20000000]= {0};//2^20次方约等于1000万,数组的大小不得小于2^20 
int b[60000]= {0};//大于5000即可 
int main() {
	int n,m,sum=0;//i,j一般都作为循环变量,最好在循环用到时再申明 
	cin>>n>>m;
	int MAX=pow(2,m)-1;//pow(i,j)=i的j次方 
	for(int i=0; i<n; i++) {
		for(int j=0; j<m; j++) {
			int t;
			cin>>t;
			   b[i]=b[i]*2+t;//计算每个答案的十进制数值 
		}
		int t=b[i];
		ans[t]++;//统计每种答案的个数 
	}
	for(int i=0; i<n; i++) {
		int t=b[i]^MAX;//取反 
		sum+=ans[t];
	}
	cout<<sum/2<<endl; 
	return 0;
}

部分思路参考:https://blog.csdn.net/weixin_42324771/article/details/87533713

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值