【Link】:http://codeforces.com/contest/831/problem/C
【Description】
有一個人參加一個比賽;
他一開始有一個初始分數x;
有k個評委要依次對這個人評分;
依照時間順序依次給出這k個人的評分(可能為負數,負數的時候,表示分數會降低,而如果為正,則分數增加);
然后有一個人記得這k次評分中的n次評分過后這個人的評分;
(即知道其中k個評委評完分之后,那個人的k個即時分數)
(這k個分數各不相同);
問你x有多少種不同可能;
【Solution】
先算出評分變化的前綴和數組pre;
然后for(int i = 1;i <= k;i++)//枚舉一個評委;
*******for (int j = 1;j <= n;j++)//枚舉一個評分{
*********int x = b[j]-pre[i];//算出第j個評分在第i個評委之后,初始評分該是什么
}
這里,要記錄下每個x,以及這個x是由第幾個評分得到的;
如果有一個x,它能由所有的n個評分都得到;
那么這個初始評分就是可行的;
因為保證b數組各不相同,
則如果有一個評分j在第i個位置獲得了初始評分x;
其他評分j’不可能在第i個位置也獲得初始評分x
這就說明,獲得初始評分x的所有n個評分肯定都是在不同的位置(即擺在不同的評委評完分之后)得到的;
相同的x,統計是不是n個評分都出現過;
是的話,遞增答案;
直接用map+set寫會超時;
于是,排序,去重,加個map,這樣時間更快;
【NumberOf WA】
3
【Reviw】
如果想到了更優的方法,就不要猶豫,盡量加快速度;
STL也不能濫用啊。
【Code】
#include <bits/stdc++.h>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define ms(x,y) memset(x,y,sizeof x)
#define Open() freopen("F:\\rush.txt","r",stdin)
#define Close() ios::sync_with_stdio(0)typedef pair<int,int> pii;
typedef pair<LL,LL> pll;
typedef set<int> myset;const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
const double pi = acos(-1.0);
const int N = 2e3;struct abc{int x,id;
};int k,n,a[N+100],b[N+100],pre[N+100],ans,tot;
map <int,int> dic;
abc c[N*N+10];bool cmp(abc a,abc b){return a.x < b.x;
}int main(){//Open();//Close();scanf("%d%d",&k,&n);rep1(i,1,k)scanf("%d",&a[i]);pre[0] = 0;rep1(i,1,k)pre[i] = pre[i-1] + a[i];rep1(i,1,n)scanf("%d",&b[i]);rep1(i,1,k){rep1(j,1,n){int x = b[j]-pre[i];tot++;c[tot].x = x,c[tot].id = j;}}sort(c+1,c+1+tot,cmp);rep1(i,1,tot){int num = n;int j = i;while (j+1<=tot && c[j+1].x==c[i].x) j++;rep1(k,i,j){if (dic[c[k].id]!=i){num--;dic[c[k].id] = i;}}if (num==0) ans++;i = j;}printf("%d\n",ans);return 0;
}/*寫完之后,明確每一步的作用
*/