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 }
    d=====( ̄▽ ̄*)b

     

posted @ 2019-10-08 23:20  连昵称都不能重复  阅读(328)  评论(0编辑  收藏  举报