标签:难题 val nsf show 双向 ring space 范围 get
假期二测
——by YYF
首先要吐槽一下出题人,从网上粘题改题目时,能不能不要把题目意思改的离原题那么远,你是想着粘下来改改就行,然后题意就大相径庭了┑( —Д — )┍
番薯&勇士
题目 |
星际搜索 |
潜入破坏 |
基因改造 |
文件 |
search.in/out |
break.in/out |
transform.in/out |
时间限制 |
1s |
1s |
1s |
空间限制 |
256m |
256m |
256m |
类型 |
传统 |
传统 |
传统 |
星际搜索(search)
题目描述
zlw成为了一位只戴一个手套的紫番薯,他带领的宇宙舰队要在茫茫星海中寻找宝石。然而宇宙航行也是要跑航线的。但是zlw的导航被ykx摧毁了,所以在航行到岔路口时必须花一天的时间来寻找航线(起始点也是岔路口),才能继续航行。为了加快搜索的效率,zlw在每个岔路口都留下了一部分的舰队,舰队在寻找完路径后同样会在原点留下一部分舰队并继续前进,并重复这一过程(每个岔路口存在无数条路径)。zlw想要知道在第n天时他能找到的路径数的个位是多少。
输入格式
一个整数n,表示天数。
输出格式
一个整数,表示路径数的个位。
输入样例
10
输出样例
8
数据范围
对于30%的数据,1<=n<=30。
对于60%的数据,1<=n<=10000000。
对于100%的数据,1<=n<=1000000000。
思路:斐波那契
我原来还以为是求2的次幂 然后就爆零了 2333
#include<algorithm> #include<cstdio> using namespace std; int n; int f[100005]; int main() { freopen("search.in","r",stdin); freopen("search.out","w",stdout); scanf("%d", &n); f[0] = 1; f[1] = 1; for(int i = 2; i <= n; i++) { f[i] = (f[i-1] + f[i-2]) % 10; } printf("%d", f[n]-1); return 0; }
潜入破坏(break)
同洛谷P1462
题目描述
破坏zlw导航的是改造人ykx,别名兄贵勇士。他为了阻止zlw的寻宝计划而秘密潜入zlw的旗舰,准备摧毁导航。而这艘旗舰实在太大了,有n个船舱,m条双向道路,每条道路都有士兵把守,与他们战斗会损失一定的生命值。现在船舱已经全部被zlw封锁了,想要突入必须用自己的能量击毁舱门。由于潜入飞船时已经耗费了大量能量,所以ykx想要知道他所经过的所有船舱中最多的一次耗费的能量的最小值是多少。
输入格式
第一行三个整数n,m,h,分别表示船舱数,道路数,ykx的生命值。
往下n行每行一个整数,代表每个船舱需要的能量数。
往下m行每行三个整数,代表一条双向路径的起点,终点,会损失的生命值。
输出格式
一个整数,为耗费的能量的最小值。
输入样例
6 8 20
6
5
4
3
2
1
1 2 1
1 3 2
2 4 3
2 5 4
3 4 5
3 5 6
4 6 7
5 6 8
输出样例
6
数据范围
对于60%的数据,满足n≤200,m≤10000,h≤200。
对于100%的数据,满足n≤10000,m≤50000,h≤1000000000。
思路:二分+spfa
#include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<cmath> #define M 1000005 using namespace std; int n, m, b, l, r; int cnt, h, t = 1; int head[M], mon[M]; int que[M], dis[M]; bool vis[M]; struct edge { int u, v, x; }ed[M]; void add(int x, int y, int z) { ed[++cnt].u = head[x]; ed[cnt].v = y; ed[cnt].x = z; head[x] = cnt; } int spfa(int top) { memset(vis, 0, sizeof(vis)); memset(dis, 50, sizeof(dis)); vis[1] = 1, dis[1] = 0, que[t] = 1, h = 0, t = 1; while(h < t) { int temp = que[++h]; if(mon[temp] > top) continue; for(int i = head[temp]; i; i = ed[i].u) if(mon[ed[i].v]<=top && dis[ed[i].v]>dis[temp]+ed[i].x) { dis[ed[i].v] = dis[temp] + ed[i].x; if(!vis[ed[i].v]) { vis[ed[i].v] = 1; que[++t] = ed[i].v; } } vis[temp] = 0; } return dis[n]; } bool judge(int mid) { spfa(mid); if(dis[n] > b) return 0; else return 1; } int main() { // freopen("break.in","r",stdin); // freopen("break.out","w",stdout); cin >> n >> m >> b; for(int i = 1; i <= n; i++) cin >> mon[i], r = max(r, mon[i]); l = max(mon[1], mon[n]); for(int i = 1; i <= m; i++) { int x, y, z; cin >> x >> y >> z; add(x, y, z); add(y, x, z); } spfa(r); if(dis[n]>=842150450 || dis[n]>b) { cout << "AFK"; return 0; } while(l <= r) { int mid = (l+r) >> 1; if(judge(mid)) r = mid-1; else l = mid+1; } cout << l; return 0; }
基因改造(transform)
同洛谷P1972
题目描述
改造兄贵勇士ykx的是著名基因科学家jss,但他改(tiao)造(jiao)ykx时遇到了一个难题。他想要知道ykx全部基因的一段基因中有多少种不同的基因。由于基因太多了,所以用数字代号表示。
输入格式
第一行一个整数n,代表基因的数目。
第二行n个整数,代表n个基因,保证每个数字代号<=n。
第三行一个整数m,代表m个询问。
往下m行,一行两个整数,表示询问的区间,保证l<=r。
输出格式
共m行,每行一个整数,代表不同的基因数。
输入样例
6
1 2 3 4 5 6
3
1 2
2 4
4 6
输出样例
2
3
3
数据范围
对于30%的数据,1<=n<=50000,1<=m<=200。
对于100%的数据,1<=n<=500000,1<=m<=20000。
思路:莫队 不会啊 qwq
#include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<bitset> #include<cmath> #define M 1000005 using namespace std; int n, m; int a[M]; int num[M]; int ans[M]; int l = 1, r, si, sum; struct ask { int l, r, id; }k[M]; bool comp(ask a, ask b) { if(a.l/si == b.l/si) return a.r < b.r; return a.l / si < b.l / si; } void add(int x) { num[x]++; if(num[x] == 1) sum++; } void del(int x) { num[x]--; if(num[x] == 0) sum--; } int main() { // freopen("transform.in","r",stdin); // freopen("transform.out","w",stdout); cin >> n; si = sqrt(n); for(int i = 1; i <= n; ++i) cin >> a[i]; cin >> m; for(int i = 1; i <= m; ++i) cin >> k[i].l >> k[i].r, k[i].id = i; sort(k+1, k+1+m, comp); for(int i = 1; i <= m; ++i) { while(r < k[i].r) { r++; add(a[r]); } while(r > k[i].r) { del(a[r]); r--; } while(l < k[i].l) { del(a[l]); l++; } while(l > k[i].l) { l--; add(a[l]); } ans[k[i].id] = sum; } for(int i = 1; i <= m; i++) cout << ans[i] << "\n"; return 0; }
标签:难题 val nsf show 双向 ring space 范围 get
原文地址:https://www.cnblogs.com/v-vip/p/9426914.html