BZOJ的思维题
5085:最大
-
给你一个n×m的矩形,要你找一个子矩形,价值为左上角左下角右上角右下角这四个数的最小值,要你最大化矩形的价值。
- 关键点是要想到把这些值排序
- 值从小到大考虑,比如说现在最小的值是(x1,yi)那一个,那我肯定不能选择它,因为我另外选四个一定得到更优解
- 所以值从小到大考虑的话,当前如果我不是没得选了,我都不会去选那些小值。
- 那假如小值是黑点,大值是白点,什么时候选四个白点作为一个矩形只有一种方案呢?
- 画一下就大概知道此时白点的数目不会超过 2*(n+m)
- 所以从大到小考虑值暴力看可不可以构成矩形就星了。
- ------在别的大佬博客上看到的做法:https://www.cnblogs.com/CQzhangyu/p/7886896.html
- 这个做法在不知道答案是在2*(n+m)以内的情况下复杂度就是n方了,orzorz
- 代码:
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <vector> 5 #define nmax 1000010 6 7 using namespace std; 8 typedef long long ll; 9 int n,m,idx=-1; 10 struct mat{ 11 int v,x,y; 12 bool operator < (const mat tcmp) const { 13 return tcmp.v<v; 14 } 15 }ma[nmax]; 16 vector <int> x[1010]; 17 int map[1010][1010]={0}; 18 19 int main(){ 20 cin>>n>>m; 21 for (int i=0; i<n; i++) for (int j=0; j<m; j++) { 22 scanf("%d",&ma[++idx].v); 23 ma[idx].x=i; 24 ma[idx].y=j; 25 } 26 sort(ma,ma+idx+1); 27 for (int i=0; i<=idx; i++) { 28 int tx = ma[i].x; 29 for (int j=0; j<x[tx].size(); j++) { 30 int ty = x[tx][j]; 31 if( map[ty][ ma[i].y ] ){ 32 cout << ma[i].v << endl; 33 return 0; 34 } 35 map[ty][ ma[i].y ] = 1; 36 map[ ma[i].y ][ty] = 1; 37 } 38 x[ ma[i].x ].push_back( ma[i].y ); 39 } 40 return 0; 41 }
2456: mode
- 给你一个n个数的数列,其中某个数出现了超过n div 2次即众数,请你找出那个数。(只能开几个变量)
- 只能说妙啊,果然bzoj无水题,刷个水题列表都如此艰难的蒟蒻枯了。
- 大概就是用后面的和它不一样的数数抵消前面的数,众数是不会被抵消完的。。康康代码就okk拉
- 代码:
1 #include <cstdio> 2 3 typedef long long ll; 4 5 int main(){ 6 int n; 7 ll in,now,cnt=1; 8 scanf("%d",&n); 9 scanf("%lld",&in); 10 now=in; 11 for (int i=1; i<n; i++) { 12 scanf("%lld",&in); 13 if(in==now) cnt++; else cnt--; 14 if(cnt<0) { now=in; cnt=1; } 15 } 16 printf("%lld\n",now); 17 return 0; 18 }