Cockroaches

Cockroaches 

题意:有n只虫,每只虫的位置都用一个横竖坐标表示,现在有一种杀虫剂,这种杀虫剂放到某一点,它能将所在它所在的行和列的所有虫杀死,现在让求出只放一个杀虫剂,最多能杀多少只虫和在满足杀最多只虫的情况下,有多少种放置方法能杀这么多只虫。

题解具体见代码

AC_Code:

 1 /*
 2 记录每个点的横纵坐标所在行列的点的数目
 3 找到最大的maxx,maxy,max_x = maxx+maxy
 4 其实消灭蟑螂的最大数目只能是max_x,或者max_x-1
 5 cnt1 :  max_x 的集合数目
 6 cnt2 :  max_x -1  集合数目
 7 */
 8 #include <bits/stdc++.h>
 9 using namespace std;
10 typedef long long ll;
11 #define endl '\n'
12 const int mod=1e9+7;
13 const int maxn=1e8+10;
14 
15 ll n;
16 map<ll,ll>cntx,cnty;
17 ll maxx,maxy;
18 ll cntx1,cntx2,cnty1,cnty2;
19 ll cnt1,cnt2;
20 ll max_x;
21 
22 int main()
23 {
24     int t,cas=0; scanf("%d",&t);
25     while( t-- ){
26         scanf("%lld",&n);
27         cntx.clear(); cnty.clear();
28         vector<pair<ll,ll>>ve(n);
29 
30         maxx=0,maxy=0;
31         for(auto &it: ve){//前面ve(n)一定要是n,不然输入不完
32             scanf("%d%d",&it.first,&it.second);
33             maxx = max(maxx, ++cntx[it.first]);
34             maxy = max(maxy, ++cnty[it.second]);
35         }
36 
37         if( cntx.size()==1 || cnty.size()==1 ){//全在一列或者全在一行
38             printf("Case %d: %lld 1\n",++cas,n);
39             continue;
40         }
41         if( maxx==1 && maxy==1 ){//每行每列都只有一只(例如对角线的情况),我们最多能杀两只,有n*(n-1)/2种情况。
42             printf("Case %d: 2 %lld\n",++cas,n*(n-1)/2);
43             continue;
44         }
45         cntx1=0,cntx2=0;
46         cnty1=0,cnty2=0;
47         for(auto &it : cntx){
48             if( it.second==maxx ) cntx1++;
49             else if( it.second==maxx-1 ) cntx2++;//就算没有maxx-1也没关系,因为maxx最多会多算一个,maxx是一定存在的,如果没有maxx-1的话,maxx会变成maxx-1,所以次大只能是maxx-1
50         }
51         for( auto &it : cnty){
52             if( it.second==maxy ) cnty1++;
53             else if( it.second==maxy-1 ) cnty2++;//就算没有maxy-1也没关系,因为maxy最多会多算一个,maxy是一定存在的,如果没有maxy-1的话,maxy会变成maxy-1,所以次大只能是maxy-1
54         }
55         max_x=maxx+maxy;
56         cnt1=cntx1*cnty1;//max_x的个数
57         cnt2=cntx1*cnty2+cnty1*cntx2;//max_x-1的个数
58 
59         for( auto &it : ve){
60             ll num=cntx[it.first]+cnty[it.second];
61             if( num==max_x){//杀虫剂放在有虫的地方,行和列交叉的地方有虫,多算了一次,这个地方其实是max_x-1
62                 cnt1--;//max_x的个数--
63                 cnt2++;//max_x-1的个数++
64             }
65             else if( num==max_x-1 ) cnt2--;//原理同上,这个地方放杀虫剂应该消灭了max_x-2只
66         }
67         if( cnt1 ){
68             printf("Case %d: %lld %lld\n",++cas,max_x,cnt1);
69         }else{
70             printf("Case %d: %lld %lld\n",++cas,max_x-1,cnt2);
71         }
72     }
73     return 0;
74 }

参考博客:here

posted @ 2020-08-10 14:38  swsyya  阅读(380)  评论(0编辑  收藏  举报

回到顶部