训练指南(白书)习题记录

来源:互联网 发布:淘宝退款率高会降权吗 编辑:程序博客网 时间:2024/06/08 17:10

第一章
UVa11636 你好世界!
ans=floor(log(n-1))+1 显然是以2为底的

#include<cstdio>#include<iostream>#include<cmath>#include<cstdlib>#include<cstring>#include<algorithm>#include<queue>#include<vector>#include<map>#define LL long long#define INF 1000000000#define eps 1e-10#define sqr(x) (x)*(x)#define pa pair<int,int>#define cyc(i,x,y) for(int i=(x);i<=(y);i++)#define cy2(i,x,y) for(int i=(x);i>=(y);i--)using namespace std;inline int read(){    int x=0,f=1;char ch=getchar();    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}    return x*f;}int main(){//  freopen("input.in","r",stdin);//  freopen("output.out","w",stdout);    int x=read(),cs=0;    while(x>=0)    {        ++cs;        if(x==1)printf("Case %d: 0\n",cs);else         printf("Case %d: %.0lf\n",cs,floor(log2(x-1))+1);        x=read();    }    return 0;}

UVa11039 设计建筑物
绝对值排一遍序

#include <iostream>#include <cstdlib>#include <cstdio>#include <cstring>#include <string>#include <algorithm>#include <cmath>using namespace std;const int MAXN = 500010;int A[MAXN];int n;int cmp(int a, int b){    return abs(a) < abs(b);}void read_case(){    scanf("%d", &n);    for(int i = 1; i <= n; i++) scanf("%d", &A[i]);    sort(A+1, A+1+n, cmp);}void solve(){    read_case();    int count = 0;    int flag = 0;    for(int i = 1; i <= n; i++)    {        if(flag == 0)        {            if(A[i] > 0) flag = 1;            else flag = 2;            count++;        }        else if(flag == 1)        {            if(A[i] < 0) {flag = 2; count++;}        }        else if(flag == 2)        {            if(A[i] > 0) {flag = 1; count++;}        }    }    printf("%d\n", count);}int main(){    int T;    scanf("%d", &T);    while(T--)    {        solve();    }    return 0;}

LA3213 古老的密码

#include <iostream>#include <cstdlib>#include <cstdio>#include <string>#include <cstring>#include <cmath>#include <vector>#include <queue>#include <stack>#include <algorithm>using namespace std;const int maxn = 1010;const int sigma_size = 26;char str1[maxn], str2[maxn];int count1[sigma_size], count2[sigma_size];void init(){    memset(count1, 0, sizeof(count1));    memset(count2, 0, sizeof(count2));}int cmp(int a, int b){    return a > b;}void solve(){    init();    for(int i = 0; str1[i]; i++) count1[str1[i]-'A']++;    for(int i = 0; str2[i]; i++) count2[str2[i]-'A']++;    sort(count1, count1+sigma_size, cmp);    sort(count2, count2+sigma_size, cmp);    for(int i = 0; i < sigma_size; i++)    {        if(count1[i] != count2[i]) { printf("NO\n"); return ;}    }    printf("YES\n");}int main(){    while(~scanf("%s%s", str1, str2))    {        solve();    }    return 0;}

LA3602 DNA序列
贪心枚举位置每次选择出现次数最多的O(mn)

#include <stdio.h> #include <string.h> const char X[] = {'A', 'C', 'G', 'T'}; int main() {     int m, n, t, i, j, d, ct[4];     char dna[50][1005];     char ans[1005];     scanf("%d", &t);     while(t--)     {         d = 0;         scanf("%d%d", &m, &n);         i = 0;         while(i < m)             scanf("%s", dna[i++]);         //统计每列各种字符数         for(j = 0; j < n; ++j)         {             memset(ct, 0, sizeof(ct));             for(i = 0; i < m; ++i)             {                 if('A' == dna[i][j]) ++ct[0];                 else if('C' == dna[i][j]) ++ct[1];                 else if('G' == dna[i][j]) ++ct[2];                 else ++ct[3];             }             //找出每列出现最多的字符            int max = -1;             char ch = 255;             for(i = 0; i < 4; ++i)             {                 if(ct[i] > max)                 {                     max = ct[i];                     ch = X[i];                 }                 else if(ct[i] == max)                     if(X[i] < ch)                         ch = X[i];             }             //计算距离             for(i = 0; i < m; ++i)                 if(dna[i][j] != ch) ++d;             ans[j] = ch;         }         ans[n] = '\0';         printf("%s\n%d\n", ans, d);     }     return 0; }

UVa10970 大块巧克力
很奇怪的一个题 ans=m*n-1 ???

#include<cstdio>#include<iostream>#include<cmath>#include<cstdlib>#include<cstring>#include<algorithm>#include<queue>#include<vector>#include<map>#define LL long long#define INF 1000000000#define eps 1e-10#define sqr(x) (x)*(x)#define pa pair<int,int>#define cyc(i,x,y) for(int i=(x);i<=(y);i++)#define cy2(i,x,y) for(int i=(x);i>=(y);i--)using namespace std;inline int read(){    int x=0,f=1;char ch=getchar();    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}    return x*f;}int n,m;int main(){//  freopen("input.in","r",stdin);//  freopen("output.out","w",stdout);    while(~scanf("%d%d",&n,&m))printf("%d\n",n*m-1);    return 0;}

UVa10382 喷水装置
贪心 只要能覆盖底边就能覆盖整个长条 转化成用最少的区间覆盖0-L
自己写的总是wa

#include<iostream>#include<cmath>#include<cstdio>#include<algorithm>#define MAXN 10005using namespace std;int n,nIndex;double l, w;struct Node{    double left;    double right;    friend bool operator < (const Node&a,const Node&b){        return a.left < b.left;    }}arr[MAXN];int main(){    double p,r;    while(scanf("%d%lf%lf",&n,&l,&w)!=EOF){        nIndex=0;        for(int i=0; i<n; ++i){            scanf("%lf%lf",&p,&r);            if(w/2>=r)                 continue; //直径小于宽度的不考虑            double t=sqrt(r*r-w*w/4.0);             arr[nIndex].left=p-t;            arr[nIndex].right=p+t;            ++nIndex;        }        sort(arr,arr+nIndex);        int cnt=0;        double left=0, right=0;        bool flag=false;        if(arr[0].left <= 0 ){            int i=0;            while(i < nIndex){                int j=i;                while(j<nIndex && left>=arr[j].left){                    if(arr[j].right > right)                        right=arr[j].right;                    ++j;                }                if(j==i) break;  // 如果上面的循环体没有执行,说明之后都没有满足的了                ++cnt;                left=right;                i=j;                if(left>=l){                    flag=true;                    break;                }            }        }        if(flag) printf("%d\n", cnt);        else printf("-1\n");    }    return 0;} 

UVa10905 孩子们的游戏
当作字符串从大到小排序 重点是cmp写法

#include<cstdio>#include<iostream>#include<cmath>#include<cstdlib>#include<cstring>#include<algorithm>#include<queue>#include<vector>#include<map>#define LL long long#define INF 1000000000#define eps 1e-10#define sqr(x) (x)*(x)#define pa pair<int,int>#define cyc(i,x,y) for(int i=(x);i<=(y);i++)#define cy2(i,x,y) for(int i=(x);i>=(y);i--)using namespace std;inline int read(){    int x=0,f=1;char ch=getchar();    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}    return x*f;}string str[51]; int cmp(string a,string b){    return a+b>b+a;}int n;int main(){//  freopen("input.in","r",stdin);//  freopen("output.out","w",stdout);    n=read();    while(n)    {        cyc(i,1,n)cin>>str[i];        sort(str+1,str+n+1,cmp);        cyc(i,1,n)cout<<str[i];cout<<endl;        n=read();    }    return 0;}

UVa10340 子序列
扫描就好了

#include<cstdio>#include<iostream>#include<cmath>#include<cstdlib>#include<cstring>#include<algorithm>#include<queue>#include<vector>#include<map>#define LL long long#define INF 1000000000#define eps 1e-10#define sqr(x) (x)*(x)#define pa pair<int,int>#define cyc(i,x,y) for(int i=(x);i<=(y);i++)#define cy2(i,x,y) for(int i=(x);i>=(y);i--)using namespace std;inline int read(){    int x=0,f=1;char ch=getchar();    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}    return x*f;}char s1[101000],s2[101000];int main(){//  freopen("input.in","r",stdin);//  freopen("output.out","w",stdout);    while(~scanf("%s %s",s1,s2))    {        int i=0,len1=strlen(s1),len2=strlen(s2);        cyc(j,0,len2-1)        {            if(s1[i]==s2[j])i++;        }        if(i!=len1)printf("No\n");        else printf("Yes\n");    }    return 0;}

LA3266 田忌赛马
贪心,细节

#include<cstdio>  #include<cstring>  #include<cmath>  #include<cstdlib>  #include<iostream>  #include<algorithm>  #include<vector>  #include<map>  #include<queue>  #include<stack> #include<string>#include<map> using namespace std;  #define LL long long  const int maxn=1005;int A[maxn],B[maxn];  int main(){    int n;    while(scanf("%d",&n)&&n){        for(int i=0;i<n;i++) scanf("%d",&A[i]);        for(int i=0;i<n;i++) scanf("%d",&B[i]);        sort(A,A+n);        sort(B,B+n);        int win=0,tag=0,i=0,j=n-1;        while(true){            int a1=A[i+tag],an=A[j],b1=B[i],bn=B[j-tag];            if(i+tag>j) break;            if(i+tag==j){                if(a1>b1) win++;                if(a1<b1) win--;                break;            }            if(a1>b1&&an>bn){                i++;j--;win+=2;            }            else if(a1>b1){i++;win++;}            else if(an>bn){j--;win++;}            else{                tag++;                if(a1<bn) win--;            }        }        printf("%d\n",win*200);    }    return 0;} 

UVa11134
贪心 两次区间选点

#include<set>#include<stdio.h>#include<algorithm>#define N 5000 + 10using namespace std;typedef struct{   int l ,r ,id;}EDGE;int AnsX[N] ,AnsY[N];EDGE X[N] ,Y[N];set<int>set1 ,set2;bool camp(EDGE a ,EDGE b){   return a.r < b.r;}int main (){   int i ,n;   int x1 ,x2 ,y1 ,y2;   while(~scanf("%d" ,&n) && n)   {      set1.clear() ,set2.clear();      for(i = 1 ;i <= n ;i ++)      {         scanf("%d %d %d %d" ,&x1 ,&y1 ,&x2 ,&y2);         X[i].l = x1 ,X[i].r = x2;         Y[i].l = y1 ,Y[i].r = y2;         X[i].id = Y[i].id = i;         set1.insert(i);         set2.insert(i);      }      set1.insert(10000000);      set2.insert(10000000);      sort(X + 1 ,X + n + 1 ,camp);      sort(Y + 1 ,Y + n + 1 ,camp);      int mk = 0;      for(i = 1 ;i <= n && !mk ;i ++)      {         int tmpx = *set1.lower_bound(X[i].l);         if(tmpx > X[i].r) mk = 1;         AnsX[X[i].id] = tmpx;         set1.erase(tmpx);         int tmpy = *set2.lower_bound(Y[i].l);         if(tmpy > Y[i].r) mk = 1;         AnsY[Y[i].id] = tmpy;         set2.erase(tmpy);      }      if(mk)      {         puts("IMPOSSIBLE");         continue;      }      for(i = 1 ;i <= n ;i ++)      printf("%d %d\n" ,AnsX[i] ,AnsY[i]);   }   return 0;}

UVa11389 巴士司机问题
容易想错

#include <algorithm>#include <iostream>#include <cstdlib>#include <cstring>#include <cstdio>#include <cmath>using namespace std;int morni[101];int after[101];int cmp1(int a, int b){ return a < b; }int cmp2(int a, int b){ return a > b; }int main(){    int n,d,r;    while (~scanf("%d%d%d",&n,&d,&r) && n) {        for (int i = 0 ; i < n ; ++ i)            scanf("%d",&morni[i]);        for (int i = 0 ; i < n ; ++ i)            scanf("%d",&after[i]);        sort(morni, morni+n, cmp1);        sort(after, after+n, cmp2);        int sum = 0;        for (int i = 0 ; i < n ; ++ i)             if (morni[i]+after[i] > d)                sum += r*(morni[i]+after[i]-d);        printf("%d\n",sum);    }     return 0;}

UVa108 最大连续子序列和
算是dp吧 f[i]表示以i结尾(包含i)的最大连续序列和
f[i]=max(f[i-1],0)+a[i],ans=max(ans,f[i])

#include<cstdio>#include<iostream>#include<cmath>#include<cstdlib>#include<cstring>#include<algorithm>#include<queue>#include<vector>#include<map>#define LL long long#define INF 1000000000#define eps 1e-10#define sqr(x) (x)*(x)#define pa pair<int,int>#define cyc(i,x,y) for(int i=(x);i<=(y);i++)#define cy2(i,x,y) for(int i=(x);i>=(y);i--)using namespace std;inline int read(){    int x=0,f=1;char ch=getchar();    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}    return x*f;}int a[101][101],f[101][101],an[101],n,T,tmp[101];int main(){//  freopen("input.in","r",stdin);//  freopen("output.out","w",stdout);        int ans=-INF;        n=read();        cyc(i,1,n)cyc(j,1,n)         a[i][j]=read();        cyc(i,1,n)cyc(j,1,n)         f[i][j]=f[i-1][j]+a[i][j];        cyc(i,1,n)cyc(j,i,n)        {            cyc(k,1,n)tmp[k]=f[j][k]-f[i-1][k];            an[1]=tmp[1];            cyc(k,2,n)            {                if(an[k-1]>0)an[k]=an[k-1]+tmp[k];                else an[k]=tmp[k];                ans=max(ans,an[k]);            }        }        printf("%d\n",ans);    return 0;}

UVa10125 和集
a+b=d-c 枚举hash查找

#include <iostream>#include <cstdlib>#include <cstdio>#include <cstring>#include <string>#include <algorithm>using namespace std;const int MAXN = 10000003;const int MAXSIZE = 1030;int n;int rear;struct node{    int i, j;}st[MAXSIZE*MAXSIZE];int first[MAXN], next[MAXSIZE*MAXSIZE];int A[MAXSIZE];int sum[MAXSIZE*MAXSIZE];void init(){    rear = 0;    memset(first, -1, sizeof(first));}int hash(int s){    int h = s & 0x7fffffff;    return h % MAXN;}void insert(int s){    int h = hash(sum[s]);    next[s] = first[h];    first[h] = s;}int find(int i, int j, int s){    int h = hash(s);    for(int v = first[h]; v != -1; v = next[v])    {        if(s == sum[v] && st[v].i != i && st[v].i != j && st[v].j != i && st[v].j != j) return 1;    }    return 0;}void read_case(){    init();    for(int i = 0; i < n; i++) scanf("%d", &A[i]);    sort(A, A+n);    for(int i = 0; i < n; i++)    {        for(int j = i+1; j < n; j++)        {            st[rear].i = i, st[rear].j = j;            sum[rear] = A[i]+A[j];            insert(rear);            rear++;        }    }}void solve(){    read_case();    for(int i = n-1; i >= 0; i--)    {        for(int j = 0; j < n; j++) if(i != j)        {            if(find(i, j, A[i]-A[j]))            {                printf("%d\n", A[i]);                return ;            }        }    }    printf("no solution\n");}int main(){    while(scanf("%d", &n) && n)    {        solve();    }    return 0;}

UVa10763 交换学生

#include<stdio.h>#include<string.h>int G[1000][1000],n;int check(){    int i,j;    for(i=0;i<1000;i++)        for(j=0;j<1000;j++)            if(G[i][j]!=0)                return 0;    return 1;}int main(){    int i,j,u,v;    while(1)    {        scanf("%d",&n);        if(n==0)            break;        memset(G,0,sizeof(G));        for(i=0;i<n;i++)        {            scanf("%d%d",&u,&v);            G[u][v]++;            G[v][u]--;        }        if(check())            printf("YES\n");        else            printf("NO\n");    }    return 0;    }
0 0
原创粉丝点击