小模擬:Q老師與十字叉

題面:

在這裏插入圖片描述輸入第一行包含一個整數 q (1 ≤ q ≤ 5 * 10^4) — 表示測試組數
對於每組數據:
第一行有兩個整數 n 和 m (1 ≤ n, m ≤ 5 * 10^4, n * m ≤ 4 * 10^5) — 表示網格圖的行數和列數
接下來的 n 行中每一行包含 m 個字符 — ‘.’ 表示這個格子是白色的, '’ 表示這個格子是黑色的
保證 q 組數據中 n 的總和不超過 5 * 10^4, n
m 的總和不超過 4 * 10^5

答案輸出 q 行, 第 i 行包含一個整數 — 表示第 i 組數據的答案

sample input:

9
5 5
..*..
..*..
*****
..*..
..*..
3 4
****
.*..
.*..
4 3
***
*..
*..
*..
5 5
*****
*.*.*
*****
..*.*
..***
1 4
****
5 5
.....
..*..
.***.
..*..
.....
5 3
...
.*.
.*.
***
.*.
3 3
.*.
*.*
.*.
4 4
*.**
....
*.**
*.**

sample output:
0
0
0
0
0
4
1
1
2

思路:

  • 因爲只需要實現一個十字架即可,所以只需要進行整個數組的遍歷然後進行最小值尋找即可
  • 需要注意他的數據範圍,看二位數組來記錄肯定會爆掉。我是用兩個一維數組分別來描述行和列,剛開始TLE是因爲const int 了一個三個數組都不會爆掉的最大範圍,用來定義三個數組,結果超時了。對三個數組分別定義最大值就能AC
  • 遍歷所有點,計算以它爲中心產生的十字架需要補多少,如果它本身是白的話,需要 -1,因爲被計算了兩次,最後輸出最小值
  • 想要複雜度更低的話,應該尋找行列中的空白最小值然後看兩個相交後需要補充的位置數,但由於他們不一定相交的位置恰好是空白點,並且最大行列不一定只有一個,記錄方法上需要細想
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
//const int N=4e5+1;
int a[50001];
int b[50001];
char mul[400001];
const int INF=1e9;
int main()
{
 int q,n,m;
 scanf("%d",&q);
 while(q--)
 {
  scanf("%d %d",&n,&m);
  int count=0;
  memset(a,0,sizeof(a));
  memset(b,0,sizeof(b));
  for(int i=0;i<n;i++)
  {
   for(int j=0;j<m;j++)
   {
    cin>>mul[count];
    if(mul[count]=='.')
     a[i]++,b[j]++;
    count++;
   }
  }
  int ans=INF;
  for(int i=0;i<n;i++)
  {
   for(int j=0;j<m;j++)
   {
    int temp=a[i]+b[j];
    if(mul[i*m+j]=='.')
    temp--;
    if(temp==0)//如果爲0說明找到不需要再填 
    {
     ans=0;
     break;
     } 
    ans=min(ans,temp);
   }
  }
  cout<<ans<<endl;
 }
 return 0;
 } 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章