解答
A Facer is learning to swim
dp , num[k][v][y] 保存在x(x>=1, x<=M) 时,深度为y(y>=1, y<=N) ,速度为v(v<=21*K, v>=0-N) 时获得最多的金钱。
B Zombies VS Plants
搜索
C Seat taking up is tough
水题, 枚举
D Ancient Vending machine
几何
E Open-air shopping malls
简单几何,二分法
F Posters
漂浮法(不造可行不), 线段树
G Hamlet‘s gambling
推理
很难的一道提,结合了字符串匹配,概率
H Graph Game
博弈, 有n个点m条边。两个人,a每次从中挑出一条边,最后希望构出一个树出来(联通图); b阻止a,阻止方法为从中丢掉一条边。最后谁赢?
I Columbus‘s bargain
这个题目简单,图论 + 单S最短路径
- 先把每两个商品看成点i、j, 如果p[i]<=p[j], 有边 i-》j,距离为p[j]-p[i]
- 然后插入savages, 即在i到j插入边, 距离为 r
- 这样一来i到j可能有2条边,懒得去重复了,原因在下方
- graph存在邻接矩阵上,djstra,用个最小堆保存最短距离值和对应点
- 两点之间如果多条边,每个点将得到多个最短距离,小丁堆只取最小的那个,其他忽略
J P2P File Sharing System
代码
#include<iostream> #include <algorithm> using namespace std; #include <map> typedef pair<int, int> Pair; #include <vector> #include <queue> // #include <priority_queue> struct cmp{ bool operator()(const Pair &a, const Pair &b){ return a.first>b.first; } }cmper; void djstra(vector<vector<Pair> > &graph, vector<int> &ds){ int n=graph.size(); vector<bool> tag(n, false); ds[0]=0, tag[0]=true; priority_queue<Pair, vector<Pair>, cmp> minq; int t=0; for(int i=1; i<n; i++){ for(int j=0; j<graph[t].size(); j++){ Pair &p=graph[t][j]; int v=p.second; if(!tag[v]){ minq.push(Pair(ds[t]+p.first, v)); } } while(!minq.empty()){ Pair p=minq.top(); minq.pop(); if(!tag[p.second]){ ds[p.second]=p.first, tag[p.second]=true; t=p.second; break; } } } } int main(){ int casen; cin>>casen; for(int ci=0; ci<casen; ci++){ int n; cin>>n; vector<int> p(n+1, -1); vector<vector<Pair> > graph(n+1, vector<Pair>()); for(int i=1; i<=n; i++){ int a; cin>>a>>p[i]; } for(int i=1; i<=n; i++){ for(int j=1; j<=n; j++){ if(p[i]<=p[j]) graph[i].push_back(Pair(p[j]-p[i], j)); } } int m; cin>>m; for(int i=0; i<m; i++){ int a, b, q; cin>>a>>b>>q; graph[a].push_back(Pair(q, b)); } // buy with one glass bead and .. for(int i=1; i<=n; i++){ graph[0].push_back(Pair(p[i]-1, i)); } vector<int> ds(n+1, -1); djstra(graph, ds); for(int i=1; i<=n; i++){ cout<<i<<" "<<ds[i]<<endl; } sort(ds.begin()+1, ds.end()); int cnt=0; for(int i=3; i<=n; i++){ for(int j=1; j<=i-2; j++){ if(binary_search(ds.begin()+j+1, ds.begin()+i, ds[i]-ds[j])) cnt++; } } cout<<cnt<<endl; } return 0; }