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

第一章
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 10005
using 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 + 10


using 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值