济南刷题冲刺 Day2 上午
2017-11-05 21:53
232 查看
P104
zhx
竞赛时间:????年??月??日??:??-??:??题目名称 | 遭遇 | 都市 | 街灯 |
名称 | meet | city | light |
输入 | meet.in | city.in | light.in |
输出 | meet.out | city.out | light.out |
每个测试点时限 | 1s | 1s | 1.5s |
内存限制 | 256MB | 256MB | 256MB |
测试点数目 | 10 | 10 | 10 |
每个测试点分值 | 10 | 10 | 10 |
是否有部分分 | 无 | 无 | 无 |
题目类型 | 传统 | 传统 | 传统 |
遭遇
【问题描述】你是能看到第一题的friends呢。
——hja
N座楼房,立于城中。
第i座楼,高度hi。
你需要一开始选择一座楼,开始跳楼。在第i座楼准备跳楼需要ci的花费。每次可以跳到任何一个还没有跳过的楼上去。但跳楼是有代价的,每次跳到另外一座楼的代价是两座楼高度的差的绝对值,最后一次从楼上跳到地面上不需要代价(只能跳到地上一次)。为在代价不超过T的情况下,最多跳几次楼。(一座楼只能跳一次,且每次跳楼都要计算准备的花费)
【输入格式】
第一行一个整数N,代表楼的数量。
接下来一行N个整数代表ci。
接下来一行N个整数代表hi。
最后一行一个整数T。
【输出格式】
一行一个整数代表答案。
【样例输入】
4
3 5 4 11
2 1 3 1
17
【样例输出】
3
【样例解释】
从1号楼跳到2号楼再跳到3号楼是一种可行的方案。
【数据范围与规定】
对于30%的数据,1≤N≤5。
对于另外20%的数据,所有hi相同。
对于另外20%的数据,ci=0。
对于100%的数据,1≤N≤50,1≤ci,hi≤10^6,1≤T≤10^7。
#include #include #include #include #define N 51 using namespace std; int dp ; struct Node { int c,h; }p ; inline void read(int &x) { x = 0; register char c = getchar(); while(!isdigit(c)) c = getchar(); while(isdigit(c)) x = x * 10 + c - '0', c = getchar(); } //dp[j] 当前在i 跳了j次 inline bool cmp(Node p,Node q) { return p.h < q.h; } int main(int argc,char *argv[]) { freopen("meet.in","r",stdin); freopen("meet.out","w",stdout); int n; read(n); for(int i=1; i<=n; ++i) read(p[i].c); for(int i=1; i<=n; ++i) read(p[i].h); sort(p + 1, p + n + 1,cmp); memset(dp,127/3,sizeof(dp)); for(int i=1; i<=n; ++i) dp[i][0] = p[i].c; for(int j=1; j<=n; ++j)//跳了 j 次 for(int i=1; i<=n; ++i) { for(int k=1; k[i]=0; --j) for(int i=n; i>j; --i) if(dp[i][j] <= T) { printf("%d\n",j + 1); fclose(stdin); fclose(stdout); return 0; } }
都市
【问题描述】你是能看到第二题的friends呢。
——laekov
塔立于都市,攀登上塔,能够到达更远的地方。但是上塔,需要破解谜题。仍然有N个数,但并不给你,而是给了你N×N-12个数,代表它们两两的和。那么,这N个数是多少呢?
【输入格式】
一行一个整数N。
接下来一行N×N-12个数,代表两两之和。
【输出格式】
第一行一个整数s代表解的个数。
接下来s行,每行N个数代表一组解,数从小到大排列。解的顺序按照字典序从大到小排列。
10f09
【样例输入1】
4
3 5 4 7 6 5
【样例输出1】
1
1 2 3 4
【样例输入2】
4
11 17 21 12 20 15
【样例输出2】
2
4 7 8 13
3 8 9 12
【数据范围与规定】
对于30%的数据,1≤N≤5,N个数均不超过10。
对于60%的数据,1≤N≤50,N个数均不超过100。
对于100%的数据,1≤N≤300,N个数均不超过10^8。
设给出的数是b1,b2,……
解为a1,a2……
那么可以得到 b1=a1+a2,b2=a1+a3
如果再知道 a2+a3=X,就可以解出a1,a2,a3
在b中把b1 b2 X 删去
剩下的最小的一定是 a1+a4,解出a4
再把a2+a4 ,a2+a4 删去,剩下的最小的一定是a1+a5
以此类推,解出所有的a
#include #include #include #include using namespace std; int n,m,tot; #define N 302 int b[N*N]; int Ans[N*N] ,t ; bool use[N*N]; void read(int &x){ x=0; register char c = getchar(); while(!isdigit(c)) c = getchar(); while(isdigit(c)) x = x * 10 + c - '0',c = getchar(); } void work(int x){ if((b[1] + b[2] + b[x]) & 1) return; t[2] = b[1] - b[2] + b[x] >> 1; t[1] = b[1] - t[2]; t[3] = b[2] - t[1]; memset(use,false,sizeof(use)); use[1] = use[2] = use[x] = true; int r,pos; for(int i=3,k=4; i<=m; ++i){ if(use[i]) continue; t[k] = b[i] - t[1]; for(int j=1; j 1 && b[i] == b[i-1]) continue; work(i); } printf("%d\n",tot); for(int i=1; i<=tot; ++i) { for(int j=1; j<=n; ++j) printf("%d ",Ans[i][j]); printf("\n"); } }
街灯
【问题描述】你是能看到第三题的friends呢。
——aoao
街上的街灯亮起,指引向着远方的路。每个街灯上都有一个数,每次询问,第l个街灯到第r个街灯上的数模p等于v的有几个。
【输入格式】
第一行两个数N,M,代表街灯的个数和询问的个数。
接下来一行N个数,代表街灯上的数。
接下来M行,每行四个数l,r,p,v代表一组询问。
【输出格式】
对于每次询问,输出一行代表答案。
【样例输入】
5 2
1 5 2 3 7
1 3 2 1
2 5 3 0
【样例输出】
2
1
【数据规模与约定】
对于30%的数据,1≤N,M≤10^3。
对于另外30%的数据,每次询问的p一样。
对于100%的数据,1≤N,M≤10^5,街灯上的数不超过10^4,1≤p≤10^9。
分析:
分块
因为街灯上的数不超过1e4,所以p最多有1e4个
用vector[i][j] 存下%i=j 的数的位置 i<=100
当p<=100 时,直接在vector[p][v] 里二分在区间[l,r]内的最左位置和最右位置
再用一个vector[i] 存下所有的街灯数位i的位置
当p>100 时,%p=v 的数 有v,v+p,v+2p……
直接枚举这些数,最多100个,在vector[i] 里 二分 在区间[l,r]内的最左位置和最右位置
#include
#include
#include
#include
#define N 100001
using namespace std;
int a
;
vector V1[101][101];
vector V2
;
inline void read(int &x) {
x = 0; register char c = getchar();
while(!isdigit(c)) c = getchar();
while(isdigit(c)) x = x * 10 + c - '0', c = getchar();
}
int main(int argc,char *argv[]){
freopen("light.in","r",stdin);
freopen("light.out","w",stdout);
int n,m; read(n),read(m);
for(int i=1; i<=n; ++i) read(a[i]);
for(int i=1; i<=n; ++i) V2[a[i]].push_back(i);
for(int i=1; i<=100; ++i)
for(int j=1; j<=n; ++j)
V1[i][a[j] % i].push_back(j);
int l,r,p,v,L,R,Mid,Ans1,pos,tot,Ans2;
while(m--) {
read(l),read(r),read(p),read(v);
Ans1 = Ans2 = -1;
if(p <= 100) {
L = 0, R = V1[p][v].size() - 1;
while(L <= R) {
Mid = L + R >> 1;
if(V1[p][v][Mid] >= l) Ans1 = Mid, R = Mid - 1;
else L = Mid + 1;
}
if(Ans1 == -1) { puts("0"); continue; }
L = Ans1, R = V1[p][v].size() - 1;
while(L <= R) {
Mid = L + R >> 1;
if(V1[p][v][Mid] <= r) Ans2 = Mid, L = Mid + 1;
else R = Mid - 1;
}
if(Ans2 == -1) { puts("0"); continue; }
printf("%d\n",Ans2 - Ans1 + 1);
}
else {
pos = v,tot = 0;
while(pos <= 10000){
L = 0,R = V2[pos].size() - 1;
Ans1 = Ans2 = -1;
while(L <= R) {
Mid = L + R >> 1;
if(V2[pos][Mid] >= l) Ans1 = Mid,R = Mid - 1;
else L = Mid + 1;
}
if(Ans1 == -1) { pos += p; continue; }
L = Ans1,R = V2[pos].size() - 1;
while(L <= R) {
Mid = L + R >> 1;
if(V2[pos][Mid] <= r) Ans2 = Mid,L = Mid + 1;
else R = Mid - 1;
}
if(Ans2 == -1) { pos += p; continue; }
tot += Ans2 - Ans1 + 1;
pos += p;
}
printf("%d\n",tot);
}
}
fclose(stdin); fclose(stdout);
return 0;
}
/*
5 2
1 5 2 3 7
1 3 2 1
2 5 3 0
*/
相关文章推荐
- 国庆清北刷题冲刺班 Day2 上午
- 济南刷题冲刺 Day2 下午
- Alpha冲刺Day2
- Beta版本冲刺Day2
- 【每日scrum】第一次冲刺day2
- Alpha冲刺Day2
- Beta冲刺---Day2
- 2016.10.30 济南学习 Day2 下午 T1
- 敏捷冲刺每日报告——Day2
- 项目Alpha冲刺Day2
- 国庆清北刷题冲刺班 Day2 下午
- alpha-咸鱼冲刺day2-紫仪
- 十天冲刺---Day2
- 团队作业7——第二次项目冲刺(Beta版本)day2
- Beta冲刺Day2
- Alpha冲刺Day2
- Day2上午解题报告
- Beta冲刺Day2
- Beta冲刺 day2
- 团队作业4——第一次项目冲刺(Alpha版本) Day2