09 conventional exercise

1001 hdu 3401

 

刚刚学过的单调队列
难度:4星

http://hi.baidu.com/edwardmj/blog/item/82fcbcc49ecc4f179d163d21.html
这个解题报告写得很清楚

 

 

1002 hdu 3452 Bonsai


 

题意:给你一棵树,每条边有一个权值,问你想让all leaf 和 root 不连通,至少要去掉的value
难度:2星
思路:搜索
想要使任一节点下的all leaf和它父节点不联通无非2 methods:
1.使该节点和父节点不联通(1条边)
2.使该节点和所有叶子不联通
use edge[x].ver[i][0] to record the index of the i-th edge vertex x connects
use edge[x].ver[i][1] to record the value of the edge above
那么对于root来说,cost=所有min(edge[r].ver[i][1],dfs(edge[r].ver[j][0]))的和

#include<iostream> 
using namespace std; 
int n,r; 
struct EDGE 

    int ver[1010][2];//weight; 
}edge[1010]; 
 
bool visited[1010]; 
int deg[1010]; 
 
int dfs(int root) 

    visited[root]=true; 
    int temp=0; 
    int ori=0; 
    if(deg[root]==1) 
        return edge[root].ver[1][1]; 
    for(int i=1;i<=deg[root];i++) 
    { 
        if(!visited[edge[root].ver[i][0]]) 
        { 
            temp+=dfs(edge[root].ver[i][0]); 
        } 
        else 
            ori=edge[root].ver[i][1]; 
    } 
    return temp<ori?temp:ori; 

 
void init() 

    int from,to,w; 
    for(int k=1;k<n;k++) 
    { 
        scanf("%d%d",&from,&to); 
        scanf("%d",&w); 
        edge[from].ver[++deg[from]][0]=to; 
        edge[to].ver[++deg[to]][0]=from; 
        edge[from].ver[deg[from]][1]=w; 
        edge[to].ver[deg[to]][1]=w; 
    } 

 
int main() 

    while(scanf("%d%d",&n,&r)!=EOF&&(n||r)) 
    { 
        for(int i=0;i<=n;i++) 
        { 
            deg[i]=0; 
            visited[i]=false; 
        } 
        init(); 
        int t=0; 
        visited[r]=true; 
        for(int j=1;j<=deg[r];j++) 
            t+=min(edge[r].ver[j][1],dfs(edge[r].ver[j][0])); 
        cout<<t<<endl; 
    } 

 

1003 hdu Code Management System

纯模拟

 

 

1004 hdu 3660 Alice and Bob's Trip

哈尔滨现场赛题目

#include <stdio.h>
#include<queue>
#include <string.h>
using namespace
std;
int
INF=0xfffffff;
#define MAXN 501000
int  Result[MAXN];
int
  Sum[MAXN];
int
  H[MAXN];
int
  Value[MAXN];
bool
V[MAXN];
int
  Gra[MAXN];
int
  Queue[MAXN];

struct
Node
{

    int
e;
    int
next;
};


Node Edge[1000000];

int
KK;//edge counter
int N,L,R;
int
MIN,MAX;

void
BSF()
{

    int
k1,k2;
    int
i,j;
    int
x,e,s;
    k1=0; k2=1;
    Queue[0]=0;

    while
(k1<k2)
    {

        x=Queue[k1];
        k1++;
        i=Gra[x];
        while
(i!=-1)
        {

            e=Edge[i].e;
            Queue[k2]=e;   k2++;
            Sum[e]=Sum[x]+Value[e];
            H[e]=1-H[x];
            i=Edge[i].next;
        }
    }


    for
(i=k2-1;i>=0;i--)
    {

        e=Queue[i];
        if
(Gra[e]==-1)
        {

            if
(Sum[e]<L||Sum[e]>R) V[e]=false;
            else
   Result[e]=Value[e];
            continue
;
        }


        MIN=INF; MAX=-INF;
        j=Gra[e];
        while
(j!=-1)
        {

            s=Edge[j].e;
            if
(!V[s]) {j=Edge[j].next; continue;}
            if
(Result[s]<MIN) MIN=Result[s];
            if
(Result[s]>MAX) MAX=Result[s];
            j=Edge[j].next;
        }

        if
(MAX+INF==0&&MIN==INF) V[e]=false;
        else

        {

            if
(H[e]) Result[e]=MIN+Value[e];
            else
     Result[e]=MAX+Value[e];
        }
    }
}


int
GetInt()
{

    int
s=0;
    char
c;
    while
(c=getchar())
    {

        if
(c<'0'||c>'9') return s;
        s=s*10+c-'0';
    }

    return
0;
}


int
main()
{

    int
a,b,x;
    int
i;
    char
c;

    while
(scanf("%d%d%d",&N,&L,&R)!=EOF)
    {

        c=getchar();
        KK=0;
        H[0]=0;
        Sum[0]=0;
        Value[0]=0;
        memset(Gra,-1,sizeof(int)*N);

        for
(i=1;i<N;i++)
        {

            //input a,b,c
            a=GetInt();
            b=GetInt();
            x=GetInt();

            //KK means the number of edges
            //use Edge to record edge

            Edge[KK].e=b;
            Edge[KK].next=Gra[a];
            Gra[a]=KK;
            KK++;

            Value[b]=x;
        }


        memset(V,true,sizeof(bool)*N);

        BSF();

        if
(!V[0]||Result[0]<L||Result[0]>R)
            printf("Oh, my god!/n");
        else

                         printf("%d/n",Result[0]);
    }

    return
0;
}

 

1005 hdu 2768 Cat vs. Dog

最大二分匹配

#include<iostream> #include<string> using namespace std; #define N 510 int troop[N][N],match[N]; int flag[N]; int n,m,ans; char s1[5],s2[5]; struct TYPE { string cid,did; }cat[N],dog[N]; int dfs(int t) { int i; for(i=0;i<=m;i++) { if(flag[i]==0&&troop[t][i]==1) { flag[i]=1; if(match[i]==-1||dfs(match[i])) { match[i]=t; return 1; } } } return 0; } int main() { int i,j,k,t,cas; scanf("%d",&cas); while(cas--) { scanf("%d%d",&n,&m); memset(match,-1,sizeof(match)); memset(troop,0,sizeof(troop)); ans=0; int cx=0,dx=0;//represent num of cat supporter and dog supporter scanf("%d",&k); for(i=0;i<k;i++) { scanf("%s%s",s1,s2); if(s1[0]=='C') { cx++; cat[cx].cid=s1; cat[cx].did=s2; } else { dx++; dog[dx].did=s1; dog[dx].cid=s2; } } for(i=1;i<=cx;i++) { for(j=1;j<=dx;j++) { if(cat[i].cid==dog[j].cid||cat[i].did==dog[j].did) troop[i][j]=1; } } n=cx,m=dx; for(i=0;i<=n;i++)//consider every region for every troop { memset(flag,0,sizeof(flag)); if(dfs(i)) ans++; } cout<<k-ans<<endl; } return 0; } 

 

1006 hdu 2779 Party Party Party

难度:2星
思路:贪心
每次找出结束当前时间下可以参加的结束时间最早的一个item,test whether it can be attended

#include<iostream>
#include<algorithm>
#include<functional>
#include<queue>
using namespace std;
bool flag[50];

struct time
{
    int start;
    int end;
    bool operator <(const time a)const
    {
        if(a.end==end)
            return a.start<start;
        return a.end<end;
    }
}now,temp;

int main()
{
    priority_queue<time>Q;
    int i,n,j=0,t;
    while(++j)
    {
        memset(flag,false,sizeof(flag));
        scanf("%d",&n);
        if(!n)
            return 0;
        for(i=0;i<n;i++)
        {
            scanf("%d%d",&now.start,&now.end);
            now.start*=2,now.end*=2;//transmit 24 hours to 48*0.5hours
            Q.push(now);
        }
        now.start=now.end=8*2;//because "The earliest a party can start is 8 AM (8) "
        int count=0;
        while(!Q.empty())
        {
            temp=Q.top();
            Q.pop();
            for(t=temp.start;t<=temp.end-1;t++)
                if(flag[t]==false)
                {
                    now.start=max(t,now.start+1);
                    flag[t]=true;
                    count++;
                    break;
                }
        }
        printf("On day %d Emma can attend as many as %d parties./n",j,count);
    }
}

 

 

 

1007 hdu 2753 Exact Change

最基础的0-1背包,即使不知道背包也可以用DP做
难度:1星
#include<iostream>
using namespace std;
#define N 100
#define M 20010
struct Status
{
 bool reach;
 int number;
}dp[M];
int v[N];

int main()
{
 int cas,i,j,T,money;
 while(scanf("%d",&T)!=EOF)
 {
  while(T--)
  {
   scanf("%d",&money);
   for(i=0;i<=money+10000;i++)
    dp[i].reach=false,dp[i].number=N;
   dp[0].reach=true,dp[0].number=0;
   scanf("%d",&cas);
   for(i=0;i<cas;i++)
   {
    scanf("%d",&v[i]);
    for(j=money+10000;j>=v[i];j--)
    {
     if(dp[j-v[i]].reach)
     {
      dp[j].reach=true;
      dp[j].number=min(dp[j].number,dp[j-v[i]].number+1);
     }
    }
   }
   for(i=money;i<=money+10000;i++)
   {
    if(dp[i].reach)
    {
     printf("%d %d/n",i,dp[i].number);
     break;
    }
   }
  }
 }
}

 

 

1008 hdu 3685 Rotational Painting

 

杭州地区赛的一道几何题
难度:4星
思路:
任何一个状态,肯定由两个点连成的一条边在支撑的,分析可知起作用的点是该多边形的凸包。若该多边形的重心到凸包上的这条边做的垂线在这条边上,则能站稳。
剩下的就是套几何模板了。

#include <iostream> #include<algorithm> #include<math.h> #define maxn 50008 using namespace std; #define eps 1e-8 #define zero(x) (((x)>0?(x):-(x))<eps) struct point {double x, y;}; struct line {point a,b;}; point p[maxn],tp[maxn]; bool mult(point sp, point ep, point op) { return (sp.x - op.x) * (ep.y - op.y) >= (ep.x - op.x) * (sp.y - op.y);} bool operator < (const point &l, const point &r) { return l.y < r.y || (l.y == r.y && l.x < r.x);} double xmulti(point p1,point p2,point p0) { return((p1.x-p0.x) * (p2.y-p0.y) -(p2.x-p0.x) * (p1.y-p0.y));} double dis(point p1,point p2){ return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)); } point intersection(line u,line v){ point ret=u.a; double t=((u.a.x-v.a.x)*(v.a.y-v.b.y)-(u.a.y-v.a.y)*(v.a.x-v.b.x)) /((u.a.x-u.b.x)*(v.a.y-v.b.y)-(u.a.y-u.b.y)*(v.a.x-v.b.x)); ret.x+=(u.b.x-u.a.x)*t; ret.y+=(u.b.y-u.a.y)*t; return ret; } point bcenter(point pnt[], int n){ point p, s; double tp, area = 0, tpx = 0, tpy = 0; p.x = pnt[0].x; p.y = pnt[0].y; for (int i = 1; i <= n; ++i) { // point: 0 ~ n-1 s.x = pnt[(i == n) ? 0 : i].x; s.y = pnt[(i == n) ? 0 : i].y; tp = (p.x * s.y - s.x * p.y); area += tp / 2; tpx += (p.x + s.x) * tp; tpy += (p.y + s.y) * tp; p.x = s.x; p.y = s.y; } s.x = tpx / (6 * area); s.y = tpy / (6 * area); return s; } //graham算法顺时针构造凸包,不包含共线点,O(nlogn) int graham(point pnt[], int n, point res[]){ int i, len, k = 0, top = 1; sort(pnt, pnt + n); if (n == 0) return 0; res[0] = pnt[0]; if (n == 1) return 1; res[1] = pnt[1]; if (n == 2) return 2; res[2] = pnt[2]; for (i = 2; i < n; i++) { while (top && mult(pnt[i], res[top], res[top-1])) top--; res[++top] = pnt[i]; } len = top; res[++top] = pnt[n - 2]; for (i = n - 3; i >= 0; i--) { while (top!=len && mult(pnt[i], res[top], res[top-1])) top--; res[++top] = pnt[i]; } return top; // 返回凸包中点的个数 } point ptoseg(point p,point l1,point l2) { point t=p; t.x+=l1.y-l2.y,t.y+=l2.x-l1.x; if (mult(l1,t,p)*mult(l2,t,p)>eps) { if(dis(p,l1)<dis(p,l2)) return l1; return l2; } line A,B; A.a=p,A.b=t; B.a=l1,B.b=l2; // return intersection(p,t,l1,l2); return intersection(A,B); } int ponls(line l,point p) {return( fabs(xmulti(l.b,p,l.a))<=eps &&( ((p.x-l.a.x)*(p.x-l.b.x)<0 ) ||((p.y-l.a.y)*(p.y-l.b.y)<0 )) );} int main() { int t, n; int i; scanf("%d", &t); while (t--) { scanf("%d", &n); for (i = 0; i < n; ++i) scanf("%lf%lf", &p[i].x, &p[i].y); point gravity = bcenter(p,n); int tnum=0; tnum=graham(p,n,tp);//凸包的点顺时针顺序存于tp point p1,p2,temp; line ll; int count=0; for(i=0;i<tnum;i++) { p1=tp[i];p2=tp[i+1]; ll.a=p1;ll.b=p2; point tt=ptoseg(gravity,p1,p2); if(ponls(ll,tt)) count++; } printf("%d/n",count); } return 0; } 

你可能感兴趣的:(c,struct,String,System,ini,methods)