题意:有n个城市,给一个矩阵,表示m件事上,n个城市的看法(东方或者西方)
现在需要确定一个分界,使得差异最小
所谓的差异,可以理解为划分后西边的E和东边的W数量和最小
直接做一个前缀和以及一个后缀和,暴力枚举分界点就行了
但是有一个陷阱:
我是将E看作1,W看作0,所以前缀和后缀都是相当于统计了1个个数
那对于前缀来说,E的个数就是前缀和本身,但是对于后缀来说,是事件个数-后缀和
坑就坑在事件个数,不是m,而是n*m
要不是学长提醒我得WA到比赛结束。。。
#include"cstdio" #include"iostream" #include"cstring" using namespace std; const int N = 1e4+5; int pre[N],suf[N],d[N][105]; int dis[N]; char arr[N]; int main(){ int n,m; while(~scanf("%d%d",&n,&m)){ for(int i=1;i<=m;i++){ scanf("%s",arr+1); for(int j=1;j<=n;j++){ if(arr[j]=='E') d[j][i]=1; else d[j][i]=0; } } for(int i=1;i<=n;i++){ dis[i]=0; for(int j=1;j<=m;j++) dis[i]+=d[i][j]; } memset(pre,0,sizeof(pre)); memset(suf,0,sizeof(suf)); for(int i=1;i<=n;i++) pre[i]=pre[i-1]+dis[i]; for(int i=n;i>0;i--) suf[i]+=suf[i+1]+dis[i]; //for(int i=1;i<=n;i++) cout<<i<<' '<<pre[i]<<' '<<suf[i]<<endl; int a=0,b=1; int minv=n*m-suf[1]; for(int i=1;i<=n;i++){ if(minv>pre[i]+(n-i)*m-suf[i+1]){ minv=pre[i]+(n-i)*m-suf[i+1]; a=i;b=i+1; } //cout<<i<<' '<<(n-i)-suf[i+1]<<endl; } printf("%d %d ",a,b); } return 0; }