COJ 1691:前缀和

题意:有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\n",a,b);
    }
    return 0;
}

 

posted @ 2016-03-14 19:34  Septher  阅读(204)  评论(0编辑  收藏  举报