您的位置:首页 > 其它

noip 2012 提高组 day2 部分题解

2016-07-22 21:38 501 查看


  这道题有多种解法,我用的是扩展欧几里得算法求到的答案

#include<iostream>
#include<fstream>
#include<cstdio>
using namespace std;
typedef long long ll;
ifstream fin("mod.in");
FILE *fout = fopen("mod.out","w");
void gcd(ll a,ll b,ll& x,ll& y){
if(!b){    x = 1, y = 0;    }
else{    gcd(b, a%b, y, x);    y -= x * (a / b);    }
}
ll a1,b1;
ll x1 = 0,y1 = 0;
int main(){
fin>>a1>>b1;
gcd(a1, b1, x1, y1);
fprintf(fout,"%ld",(x1 + b1 * 2)%b1);
return 0;
}






  这道题把第i个人看做一个有序的序列(1、2、3、4....)然后二分

至于求和,就像这么处理:

  



接着从前面开始求和。。。



就像这样可以求出每一天的教室使用量,如果1 ~ v天中有哪一天不够用了,就在前半段

查找,如果都足够,就向后面查找,每次不够的时候更新结果result

#include<iostream>
#include<fstream>
#include<cstdio>
#include<cctype>
#include<cstring>
using namespace std;
typedef bool boolean;
FILE *fout = fopen("classroom.out","w");
template <class T>
inline void get(T &u){
char x;
while(!isdigit(x=getchar()));
for( u=x-48; isdigit(x=getchar()); u*=10,u+=(x-48));
ungetc(x,stdin);
}
int *d;
int *s;
int *t;
int *r;
int *buf;
int m,n;
boolean solve(int v){
memset(buf, 0, sizeof(int) * (n + 1));
int sum = 0;
int limit = 0;
for(int i = 1;i <= v;i++){
buf[s[i]] += d[i];
buf[t[i] + 1] -= d[i];
limit = max(limit, t[i]);
}
for(int i = 1;i <= limit;i++){
sum += buf[i];
if(sum > r[i])    return true;
}
return false;
}
int main(){
freopen("classroom.in","r",stdin);
get(n);
get(m);
r = new int[(const int)(n + 1)];
d = new int[(const int)(m + 1)];
s = new int[(const int)(m + 1)];
t = new int[(const int)(m + 1)];
buf = new int[(const int)(n + 1)];
for(int i = 1;i <= n;i++)    get(r[i]);
for(int i = 1;i <= m;i++){
get(d[i]);
get(s[i]);
get(t[i]);
}
int from = 1;
int end = m;
int result = 0;
while(from <= end){
int mid = (from + end) >> 1;
if(solve(mid)){
result = mid;
end = mid - 1;
}else from = mid + 1;
}
if(!result)    fprintf(fout,"0\n");
else fprintf(fout,"-1\n%d\n",result);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: