这场比赛各种手贱。。。
UVA 地址:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=523
A:不能多说。比赛的时候我也不知道哪里手贱了。反正就是过不了。。。最水的一道题。。代码就不贴了。。
B。
C。
D,其实这也是一道水题,当时居然没看。
题意:给你N个树的坐标(x,y)。现在有一些道路,这些道路都是平行坐标轴的,输入的时候是这样的 (H 1) ,代表水平方向,Y = 1的时候有一条道路,同理(V 1) 。
现在问你,一个观察员在这些道路上,垂直着看过去,总共可以看到K棵树,问K / N 是否大于60%。
这道题很水啊,直接对着这N棵树的横坐标和纵坐标找在这些道路中的上下界,然后判断在这些上下界之间是否还有其他树挡住,没有的话就标记1,用lower_bound和upper_bound就可以了。
#include <set> #include <map> #include <stack> #include <cmath> #include <queue> #include <cstdio> #include <string> #include <vector> #include <iomanip> #include <cstring> #include <iostream> #include <algorithm> #define Max 2505 #define FI first #define SE second #define ll long long #define PI acos(-1.0) #define inf 0x3fffffff #define LL(x) ( x << 1 ) #define bug puts("here") #define PII pair<int,int> #define RR(x) ( x << 1 | 1 ) #define mp(a,b) make_pair(a,b) #define mem(a,b) memset(a,b,sizeof(a)) #define REP(i,s,t) for( int i = ( s ) ; i <= ( t ) ; ++ i ) using namespace std; #define N 1111111 int n , m ; PII a[N] ; bool cmp(PII x , PII y){ if(x.FI == y.FI)return x.SE < y.SE ; return x.FI < y.FI ; } bool cmp1(PII x, PII y){ if(x.SE == y.SE)return x.FI < y.FI ; return x.SE < y.SE ; } int vec[N] ; int hor[N] ; int H , V ; bool vis[N] ; void init(){ mem(vis ,0) ; H = V = 0 ; } int main() { int T ; cin >> T ; while(T -- ){ cin >> n >> m ; init() ; char str[111] ; REP(i , 0 , n - 1)scanf("%d%d",&a[i].FI ,&a[i].SE) ; REP(i , 0 , m - 1){ int d ; scanf("%s%d",str , &d) ; if(str[0] == 'H')hor[H ++] = d ; else vec[V ++ ] = d ; } hor[H ++] = inf ; hor[H ++] = -inf ; vec[V ++] = inf ; vec[V ++] = -inf ; sort(a , a + n , cmp) ;//按y优先排序 sort(hor , hor + H) ; sort(vec , vec + V) ; for (int i = 0 ; i < n ; i ++ ){ int x = lower_bound(hor , hor + H , a[i].SE) - hor - 1 ;//纵坐标,找下界 if(x != 0 && (i == 0 || a[i - 1].FI != a[i].FI || a[i - 1].SE < hor[x])){//如果不为-inf,并且该点是这一列的最低点,或者该点下面的点小于该下界。 vis[i] = 1 ; continue ; } x = upper_bound(hor , hor + H , a[i].SE) - hor ; if(x != H - 1 && (i == 0 || a[i + 1].FI != a[i].FI || a[i + 1].SE > hor[x])){//如果不为inf ,并且该点是这列的最高点,或者该点上面的点大于该上界 vis[i] = 1 ; } } sort(a , a + n , cmp1) ;//按x优先排序 for (int i = 0 ; i < n ; i ++ ){//同理 if(vis[i])continue ; int x = lower_bound(vec , vec + V , a[i].FI) - vec - 1 ; // cout << a[i].FI << endl; // cout << i << " " << x << endl; if(x != 0 && (i == 0 || a[i - 1].SE != a[i].SE || a[i - 1].FI < vec[x])){ vis[i] = 1 ; continue ; } x = upper_bound(vec , vec + V , a[i].FI) - vec ; if(x != V - 1 && (i == 0 || a[i + 1].SE != a[i].SE || a[i + 1].FI > vec[x])){ vis[i] = 1 ; } } int ans = 0 ; for (int i = 0 ; i < n ; i ++ )if(vis[i])ans ++ ; // cout << ans << endl; if(ans * 1.0 / n > 0.6)puts("PASSED") ; else puts("FAILED") ; } return 0 ; } /* 1 6 3 -1 3 4 2 6 2 6 3 6 4 4 3 H -1 V 0 H 5 */E,题意:给出2组数,上面一组如果能两两组合成一个数并且等于下面一组数的话,那么算一个匹配。
思路:简单的二分匹配。
#include <set> #include <map> #include <stack> #include <cmath> #include <queue> #include <cstdio> #include <string> #include <vector> #include <iomanip> #include <cstring> #include <iostream> #include <algorithm> #define Max 2505 #define FI first #define SE second #define ll long long #define PI acos(-1.0) #define inf 0x3fffffff #define LL(x) ( x << 1 ) #define bug puts("here") #define PII pair<int,int> #define RR(x) ( x << 1 | 1 ) #define mp(a,b) make_pair(a,b) #define mem(a,b) memset(a,b,sizeof(a)) #define REP(i,s,t) for( int i = ( s ) ; i <= ( t ) ; ++ i ) using namespace std; int n , m ; int Map[555][555] ; int x[555] ; int y[555] ; int link[555] ; bool vis[555] ; int find(int now){ for (int i = 1 ; i <= n ; i ++ ){ if(!vis[i] && Map[now][i]){ vis[i] = 1 ; if(link[i] == -1 || find(link[i])){ link[i] = now ; return 1 ; } } } return 0 ; } int main() { int T ; cin >> T ; while(T -- ){ map<int ,int>M ; cin >> n >> m ; mem(link ,-1) ; for (int i = 1 ; i <= n ; i ++ )cin >> x[i] ; for (int j = 1 ; j <= m ; j ++ ){ cin >> y[j] ; } mem(Map ,0) ; for (int i = 1 ; i <= n ; i ++ ){ for (int j = 1 ; j <= n ; j ++ ){ if(i == j)continue ; for (int k = 1 ; k <= m ; k ++ ){ if(x[i] + x[j] == y[k]){ Map[i][j] = 1 ; } } } } // for (int i = 1 ; i <= n ; i ++ ){} int ans = 0 ; for (int i = 1 ; i <= n ; i ++ ){ mem(vis ,0) ; ans += find(i) ; } cout << ans / 2 << endl;//无向图除以2 } return 0 ; } /* 2 6 4 1 2 3 4 4 5 6 9 3 5 5 4 1 2 3 4 5 6 9 3 5 */
G,当时想太多了,直接HASH就可以了。。
这里是字符串HASH的函数。
https://www.byvoid.com/blog/string-hash-compare/
用的BKDRHash的方法。
#define N 111111 unsigned int BKDRHash(char *str) {//hash函数,本题没用。 unsigned int seed = 31; // 31 131 1313 13131 131313 etc.. unsigned int hash = 0; while (*str) { hash = hash * seed + (*str++); } return (hash & 0x7FFFFFFF); } char x[N] ; char y[N] ; int main() { int T ; cin >> T ; while( T -- ) { cin >> x >> y ; int lx = strlen(x) ; int ly = strlen(y) ; int posx = lx - 1 ; int posy = 0 ; unsigned int hashx = 0 ; unsigned int hashy = 0 ; int ans = 0 ; unsigned int seed = 31 ; int Hx = 1 ; while(posx >= 0 && posy < ly) { hashx += Hx * x[posx] ; hashy = hashy * seed + y[posy] ; hashx &= 0x7fffffff ; hashy &= 0x7fffffff ; if(hashx == hashy)ans ++ ; Hx *= seed ; posx -- ; posy ++ ; } cout << ans + 1 << endl; } return 0 ; } /* 3 xyzabcabc abcabcxyz xyzabc abcxyz sda fdsaf */H。最水的BFS。
#include <set> #include <map> #include <stack> #include <cmath> #include <queue> #include <cstdio> #include <string> #include <vector> #include <iomanip> #include <cstring> #include <iostream> #include <algorithm> #define Max 2505 #define FI first #define SE second #define ll long long #define PI acos(-1.0) #define inf 0x3fffffff #define LL(x) ( x << 1 ) #define bug puts("here") #define PII pair<int,int> #define RR(x) ( x << 1 | 1 ) #define mp(a,b) make_pair(a,b) #define mem(a,b) memset(a,b,sizeof(a)) #define REP(i,s,t) for( int i = ( s ) ; i <= ( t ) ; ++ i ) using namespace std; #define N 1111 double x[N] , y[N] ; int n , s , e ; double l , r ; //double Map struct kdq{ int e , next ; }ed[N * 1111] ; int head[N] , num ; void add(int s ,int e){ ed[num].e = e ;ed[num].next = head[s] ; head[s] = num ++ ; } void init(){ mem(head ,-1) ; num = 0 ; } double getdis(int i, int j){ return sqrt((x[i] - x[j]) * (x[i] - x[j]) * 1.0 + 1.0 * (y[i] - y[j]) * (y[i] - y[j])) ; } #define eps 1e-5 void ok(int i ,int j){ double dis = getdis(i , j) ; if(l + r - dis > eps)add(i , j ) ; if(fabs(dis - l - r) < eps){ add(i , j) ; } } bool vis[N] ; int qe[N * 10] ; int dis[N] ; int bfs(){ mem(vis , 0) ; vis[s] = 1 ; for (int i = 0 ; i < N ; i ++ )dis[i] = inf ; dis[s] = 0 ; int h = 0 , t = 0 ; qe[h ++ ] = s ; while(h > t){ int tmp = qe[t ++ ]; if(tmp == e){ return dis[tmp] ; } for(int i = head[tmp] ; ~i ; i = ed[i].next ){ int ee = ed[i].e ; if(!vis[ee] && dis[ee] > dis[tmp] + 1){ dis[ee] = dis[tmp] + 1 ; qe[h ++ ] = ee ; vis[ee] = 1 ; } } } return 0 ; } int main() { int tt ; cin >> tt ; while(tt -- ){ cin >> n >> s >> e >> l >> r ; init() ; for (int i = 1 ; i <= n ; i ++ ){ scanf("%lf%lf",&x[i] , &y[i]) ; } for (int i = 1 ; i <= n ; i ++ ){ for (int j = 1 ; j <= n ; j ++ ){ if(i == j)continue ; ok(i , j) ; } } if(s == e){ cout << 0 << endl; continue ; } int ans = bfs() ; if(!ans)puts("Impossible") ; else cout << ans << endl; } return 0 ; } /* 2 4 1 4 2 1 0 0 0 4 4 0 4 4 9 1 4 2 3 0 7 -6 2 -3 3 6 2 -6 -3 3 -3 6 -3 -3 -7 0 -7 */