题目链接:
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=89134#overview
密码:
431
1.Xenia and Bit Operations
题目链接:
http://codeforces.com/problemset/problem/339/D
解题思路:
http://blog.csdn.net/piaocoder/article/details/47909667
AC代码:
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn = 1<<17+5;
struct node{
int l,r;
int sum;
}tree[maxn<<2];
int a[maxn];
void build(int id,int l,int r,int op){
tree[id].l = l;
tree[id].r = r;
if(l == r){
tree[id].sum = a[l];
return;
}
int mid = (l+r)>>1;
build(id<<1,l,mid,-op);
build(id<<1|1,mid+1,r,-op);
if(op == 1)
tree[id].sum = tree[id<<1].sum^tree[id<<1|1].sum;
else
tree[id].sum = tree[id<<1].sum|tree[id<<1|1].sum;
}
void update(int id,int x,int val,int op){
if(tree[id].l == x && tree[id].r == x){
tree[id].sum = val;
return;
}
int mid = (tree[id].l+tree[id].r)>>1;
if(x <= mid)
update(id<<1,x,val,-op);
else
update(id<<1|1,x,val,-op);
if(op == 1)
tree[id].sum = tree[id<<1].sum^tree[id<<1|1].sum;
else
tree[id].sum = tree[id<<1].sum|tree[id<<1|1].sum;
}
int query(int id,int l,int r){
if(tree[id].l == l && tree[id].r == r){
return tree[id].sum;
}
int mid = (tree[id].l+tree[id].r)>>1;
if(r <= mid)
return query(id<<1,l,r);
if(l > mid)
return query(id<<1|1,l,r);
return query(id<<1,l,mid)^query(id<<1|1,mid+1,r);
}
int main(){
int n,m;
while(~scanf("%d%d",&n,&m)){
int num = 1<<n,op;
for(int i = 1; i <= num; i++)
scanf("%d",&a[i]);
if(n&1)
op = -1;//或
else
op = 1;//异或
build(1,1,num,op);
int a,b;
while(m--){
scanf("%d%d",&a,&b);
update(1,a,b,op);
printf("%d\n",query(1,1,num));
}
}
return 0;
}
2.棋盘问题
题目链接:
http://poj.org/problem?id=1321
解题思路:
http://blog.csdn.net/piaocoder/article/details/47909867
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int n,m;
char node[10][10];
int vis[10];
int ans;
void dfs(int row,int sum){
if(sum == m){
ans++;
return;
}
if(row > n)
return;
for(int j = 1; j <= n; j++){
if(node[row][j] == '#' && !vis[j]){
vis[j] = 1;
dfs(row+1,sum+1);
vis[j] = 0;
}
}
dfs(row+1,sum);
//这步很关键,想上去了,这题就成了水题,想不上去的话。。。
//当k<n时,row在等于n之前就可能已经把全部棋子放好
//又由于当全部棋子都放好后的某个棋盘状态已经在前面循环时记录了
//因此为了处理多余行,令当前位置先不放棋子,搜索在下一行放棋子的情况
}
int main(){
while(~scanf("%d%d",&n,&m)){
if(n+m < 0)
break;
for(int i = 1; i <= n; i++)
scanf("%s",node[i]+1);
ans = 0;
memset(vis,0,sizeof(vis));
dfs(1,0);
printf("%d\n",ans);
}
return 0;
}
3.Osu!
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=5078
解题思路:
先将每个点按时间排个序,再找距离/时间差的最大值
AC代码:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
struct node{
int t;
double x,y;
}no[1005];
double dis(double x1,double y1,double x2,double y2){
return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
bool cmp(node a,node b){
return a.t < b.t;
}
int main(){
int T;
scanf("%d",&T);
while(T--){
int n;
scanf("%d",&n);
double sum = 0;
for(int i = 1; i <= n; i++)
scanf("%d%lf%lf",&no[i].t,&no[i].x,&no[i].y);
sort(no+1,no+n+1,cmp);
for(int i = 2; i <= n; i++){
sum = max(sum,dis(no[i].x,no[i].y,no[i-1].x,no[i-1].y)/(no[i].t-no[i-1].t));
}
printf("%.10lf\n",sum);
}
return 0;
}
4.Billboard
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=2795
解题思路:
http://blog.csdn.net/piaocoder/article/details/47910001
AC代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 200005;
struct node{
int l,r;
int num;
}tree[N<<2];
int h,w,n;
void build(int id,int l,int r){
tree[id].l = l;
tree[id].r = r;
tree[id].num = w;
if(l == r)
return ;
int mid = (l+r)>>1;
build(id<<1,l,mid);
build(id<<1|1,mid+1,r);
}
int query(int id,int len){
if(tree[id].l == tree[id].r){
tree[id].num -= len;
return tree[id].l;
}
else{
int sum1 = 0,sum2 = 0;
if(len <= tree[id<<1].num)
sum1 = query(id<<1,len);
else if (len <= tree[id<<1|1].num)
sum2 = query(id<<1|1,len);
tree[id].num = max(tree[id<<1].num,tree[id<<1|1].num);
return sum1+sum2;
}
}
int main(){
while(~scanf("%d%d%d",&h,&w,&n)){
if(h > n)
h = n;
build(1,1,h);
int x;
for(int i = 1; i <= n; i++){
scanf("%d",&x);
if(tree[1].num >= x)
printf("%d\n",query(1,x));
else
printf("-1\n");
}
}
return 0;
}
5.Minimum Transport Cost
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1385
解题思路:
http://blog.csdn.net/piaocoder/article/details/47910271
AC代码:
#include <iostream>
#include <cstdio>
using namespace std;
const int INF = 0xfffffff;
const int N = 105;
int n;
int edge[N][N];
int path[N][N];
int charge[N];
void floyd(){
for(int k = 1; k <= n; k++){
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++){
if(edge[i][k] != INF && edge[k][j] != INF){
int tmp = edge[i][k]+edge[k][j]+charge[k];
if(edge[i][j] > tmp){
edge[i][j] = tmp;
path[i][j] = path[i][k];
}
else if(edge[i][j] == tmp && path[i][j] > path[i][k])
path[i][j] = path[i][k];
}
}
}
}
}
int main(){
while(scanf("%d",&n),n){
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++){
scanf("%d",&edge[i][j]);
if(edge[i][j] == -1)
edge[i][j] = INF;
path[i][j] = j;
}
}
for(int i = 1; i <= n; i++)
scanf("%d",&charge[i]);
floyd();
int from,to;
while(scanf("%d%d",&from,&to)){
if(from == -1 && to == -1)
break;
printf("From %d to %d :\n",from,to);
printf("Path: ");
int cur = from;
printf("%d",cur);
while(cur != to){
printf("-->%d",path[cur][to]);
cur = path[cur][to];
}
puts("");
printf("Total cost : %d\n\n", edge[from][to]);
}
}
return 0;
}
6.Phone List
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1671
解题思路:
http://blog.csdn.net/piaocoder/article/details/47951011
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
char str[10005][15];
struct node
{
int cnt;
struct node *next[10];
node()
{
cnt=0;
memset(next,0,sizeof(next));
}
};
node *root = NULL;
void buildtrie(char *s)
{
node *p=root;
node *tmp=NULL;
int i,l=strlen(s);
for(i=0;i<l;i++)
{
if(p->next[s[i]-'0']==NULL)
{
tmp=new node;
p->next[s[i]-'0']=tmp;
}
p=p->next[s[i]-'0'];
p->cnt++;
}
}
bool findtrie(char *s)
{
node *p=root;
int i,l=strlen(s);
for(i=0;i<l;i++)
p=p->next[s[i]-'0'];
if(p->cnt != 1)
return true;
return false;
}
void del(node *root)
{
for(int i=0;i<10;i++)
if(root->next[i])
del(root->next[i]);
delete(root);
}
int main()
{
int T;
scanf("%d",&T);
while(T--){
root = new node;
int n;
scanf("%d",&n);
for(int i = 1; i <= n; i++){
scanf("%s",str[i]);
buildtrie(str[i]);
}
int flag = 1;
for(int i = 1; i <= n; i++){
if(findtrie(str[i])){
flag = 0;
break;
}
}
if(flag)
printf("YES\n");
else
printf("NO\n");
del(root);
}
return 0;
}
7.Einbahnstrasse
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=2923
解题思路:
题意:一开始给出三个数字,n,c,m,代表城市数,破车数,道路数
然后给你m条路线,箭头为方向,数字为花费,然后求出从公司派出车,到每个城市回收破车的最小花费,需要注意每辆车只能回收
一辆破车
用floyd求最短路。。。
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <map>
#define INF 0xfffffff
using namespace std;
int n,c,m;
int edge[110][110];
string str[1005];
map<string,int> mm;
void floyd(){
for(int k = 1; k <= n; k++)
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
edge[i][j] = min(edge[i][j],edge[i][k]+edge[k][j]);
}
int main(){
int t = 1;
while(scanf("%d%d%d",&n,&c,&m),n+c+m){
mm.clear();
for(int i = 1; i <= n; i++){
edge[i][i] = 0;
for(int j = 1; j < i; j++)
edge[i][j] = edge[j][i] = INF;
}
for(int i = 0; i <= c; i++)
cin>>str[i];
string s1,s2;
char op1,op2,tmp1,tmp2;
int num,id = 1;
for(int i = 0; i < m; i++){
cin>>s1>>op1>>tmp1>>num>>tmp2>>op2>>s2;
if(!mm[s1])
mm[s1] = id++;
if(!mm[s2])
mm[s2] = id++;
if(op1 == '<')
edge[mm[s2]][mm[s1]] = min(edge[mm[s2]][mm[s1]],num);
if(op2 == '>')
edge[mm[s1]][mm[s2]] = min(edge[mm[s1]][mm[s2]],num);
}
floyd();
int start = mm[str[0]];
int sum = 0;
for(int i = 1; i <= c; i++)
sum += edge[start][mm[str[i]]]+edge[mm[str[i]]][start];
printf("%d. %d\n",t++,sum);
}
return 0;
}
8.Arctic Network
题目链接:
http://poj.org/problem?id=2349
解题思路:
http://blog.csdn.net/piaocoder/article/details/47910955
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define INF 0xfffffff
using namespace std;
struct node{
double x,y;
}no[505];
int s,p,ans;
double edge[505][505];
double dis[505];
double temp[505];
int vis[505];
double dist(double x1,double y1,double x2,double y2){
return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
bool cmp(double x,double y){
return x > y;
}
void prim(int cur)
{
int i, j, tmp;
memset(vis, 0, sizeof(vis));
for(i = 1; i <= p; i++)
dis[i] = edge[cur][i];
vis[cur] = 1;
for(i = 2; i <= p; i++)
{
double Min = INF;
for(j = 1; j <= p; j++)
{
if(!vis[j] && dis[j] < Min)
Min = dis[tmp = j];
}
vis[tmp] = 1;
temp[ans++] = Min;
for(j = 1; j <= p; j++)
{
if(!vis[j] && dis[j] > edge[tmp][j])
dis[j] = edge[tmp][j];
}
}
}
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d",&s,&p);
for(int i = 1; i <= p; i++)
scanf("%lf%lf",&no[i].x,&no[i].y);
for(int i = 1; i <= p; i++){
edge[i][i] = 0;
for(int j = 1; j < i; j++){
edge[i][j] = edge[j][i] = dist(no[i].x,no[i].y,no[j].x,no[j].y);
}
}
ans = 0;
prim(1);
sort(temp,temp+ans,cmp);
printf("%.2f\n",temp[s-1]);
}
return 0;
}