这场比赛各种手贱。。。
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
*/