noip 2012 提高组 day2 部分题解
这道题有多种解法,我用的是扩展欧几里得算法求到的答案
1 #include<iostream> 2 #include<fstream> 3 #include<cstdio> 4 using namespace std; 5 typedef long long ll; 6 ifstream fin("mod.in"); 7 FILE *fout = fopen("mod.out","w"); 8 void gcd(ll a,ll b,ll& x,ll& y){ 9 if(!b){ x = 1, y = 0; } 10 else{ gcd(b, a%b, y, x); y -= x * (a / b); } 11 } 12 ll a1,b1; 13 ll x1 = 0,y1 = 0; 14 int main(){ 15 fin>>a1>>b1; 16 gcd(a1, b1, x1, y1); 17 fprintf(fout,"%ld",(x1 + b1 * 2)%b1); 18 return 0; 19 }
这道题把第i个人看做一个有序的序列(1、2、3、4....)然后二分
至于求和,就像这么处理:
、
接着从前面开始求和。。。
就像这样可以求出每一天的教室使用量,如果1 ~ v天中有哪一天不够用了,就在前半段
查找,如果都足够,就向后面查找,每次不够的时候更新结果result
1 #include<iostream> 2 #include<fstream> 3 #include<cstdio> 4 #include<cctype> 5 #include<cstring> 6 using namespace std; 7 typedef bool boolean; 8 FILE *fout = fopen("classroom.out","w"); 9 template <class T> 10 inline void get(T &u){ 11 char x; 12 while(!isdigit(x=getchar())); 13 for( u=x-48; isdigit(x=getchar()); u*=10,u+=(x-48)); 14 ungetc(x,stdin); 15 } 16 int *d; 17 int *s; 18 int *t; 19 int *r; 20 int *buf; 21 int m,n; 22 boolean solve(int v){ 23 memset(buf, 0, sizeof(int) * (n + 1)); 24 int sum = 0; 25 int limit = 0; 26 for(int i = 1;i <= v;i++){ 27 buf[s[i]] += d[i]; 28 buf[t[i] + 1] -= d[i]; 29 limit = max(limit, t[i]); 30 } 31 for(int i = 1;i <= limit;i++){ 32 sum += buf[i]; 33 if(sum > r[i]) return true; 34 } 35 return false; 36 } 37 int main(){ 38 freopen("classroom.in","r",stdin); 39 get(n); 40 get(m); 41 r = new int[(const int)(n + 1)]; 42 d = new int[(const int)(m + 1)]; 43 s = new int[(const int)(m + 1)]; 44 t = new int[(const int)(m + 1)]; 45 buf = new int[(const int)(n + 1)]; 46 for(int i = 1;i <= n;i++) get(r[i]); 47 for(int i = 1;i <= m;i++){ 48 get(d[i]); 49 get(s[i]); 50 get(t[i]); 51 } 52 int from = 1; 53 int end = m; 54 int result = 0; 55 while(from <= end){ 56 int mid = (from + end) >> 1; 57 if(solve(mid)){ 58 result = mid; 59 end = mid - 1; 60 }else from = mid + 1; 61 } 62 if(!result) fprintf(fout,"0\n"); 63 else fprintf(fout,"-1\n%d\n",result); 64 return 0; 65 }