ALGO-194 审美课

算法训练 审美课
时间限制:1.0s 内存限制:256.0MB

问题描述
  《审美的历程》课上有n位学生,帅老师展示了m幅画,其中有些是梵高的作品,另外的都出自五岁小朋友之手。老师请同学们分辨哪些画的作者是梵高,但是老师自己并没有答案,因为这些画看上去都像是小朋友画的……老师只想知道,有多少对同学给出的答案完全相反,这样他就可以用这个数据去揭穿披着皇帝新衣的抽象艺术了(支持帅老师_)。
  答案完全相反是指对每一幅画的判断都相反。
输入格式
  第一行两个数n和m,表示学生数和图画数;
  接下来是一个n*m的01矩阵A:
  如果aij=0,表示学生i觉得第j幅画是小朋友画的;
  如果aij=1,表示学生i觉得第j幅画是梵高画的。
输出格式
  输出一个数ans:表示有多少对同学的答案完全相反。
样例输入
3 2
1 0
0 1
1 0
样例输出
2
样例说明
  同学1和同学2的答案完全相反;
  同学2和同学3的答案完全相反;
  所以答案是2。
数据规模和约定
  对于50%的数据:n<=1000;
  对于80%的数据:n<=10000;
  对于100%的数据:n<=50000,m<=20。

解题思路

刚开始想的暴力,感觉应该不是这样的,就算成功也会超时。百度了一下dalao的做法。
总结一句就是。。。看不懂。。
位或运算只是知道一些皮毛,STL中的map更是没有用过。。。顿时发现自己渣的一匹。。
研究了各位dalao的代码和解题思路之后差不多是看懂了,但是还有部分不知道为什么要这么算
总结一下:
将每一行的两个数转换为十进制的。
将一样的十进制数放在同一个容器里
遍历map,求每一个的相反数,在去给sum加上相反数下标的数组的值
这样必定会有一次重复,最后在对结果/2就行了

关于运算:
a << = 1 ; //a左移一位等效于a = a * 2;
a << = 2 ; //a左移2位等效于a = a * 2的2次方(4);
异或运算符的规则是:相反为1,相同为0
即:0^0=0
1^1=0
0^1=1
1^0=1

问题:

  1. 其中的数组定义在main函数内的时候,输入完第一组数据之后就会崩溃
  2. int max = (1<<m)-1; 能看懂是怎么计算,但是不明白为什么这么算

完整代码

#include<iostream> 
#include<map>
using namespace std;
int a[50007];//存二进制
map<int,int> ans;
//int ans[2000000]={0};
int main()
{
	int n,m;
	cin>>n>>m;
	
	int sum=0;
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<m;j++)
		{
			int t;
			cin>>t;
			a[i]=(a[i]<<1)+t;//转换二进制为十进制(一个i对应一个)
		}
		ans[a[i]]++;//记录一样的答案
	}
	int max = (1<<m)-1;//1*(2^m)-1
	for(int i=0;i<n;i++)//按行选择相反数
	{
		int t = a[i]^max;//求相反的那个数的十进制(过程用的二进制)
		sum += ans[t];//答案数加上相反的那个答案集的个数
		//答案集的个数后面还会在加一次这次的加数,所以最后sum/2
	}
	cout<<sum/2;
	return 0;
} 

大佬们可否帮我解答一下以上的问题,谢!

猜你喜欢

转载自blog.csdn.net/DanBo_C/article/details/88184414
今日推荐