紫书第三章习题

时间:2022-06-26 00:15:18

UVA 1585

这题我居然wa了3次,看来我真的好渣,想了想我的是当只有一个O的时候越界了,果然还是代码风格太差,需要改进!!

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int INF=0x3f3f3f3f;
const ll LINF=0x3f3f3f3f3f3f3f3f;
#define PI(A) cout<<(A)<<endl
#define SI(N) cin>>(N)
#define SII(N,M) cin>>(N)>>(M)
#define cle(a,val) memset(a,(val),sizeof(a))
#define rep(i,b) for(int i=0;i<(b);i++)
#define Rep(i,a,b) for(int i=(a);i<=(b);i++)
#define reRep(i,a,b) for(int i=(a);i>=(b);i--)
#define dbg(x) cout <<#x<<" = "<<(x)<<endl
#define PIar(a,n) rep(i,n)cout<<a[i]<<" ";cout<<endl;
#define PIarr(a,n,m) rep(aa,n){rep(bb, m)cout<<a[aa][bb]<<" ";cout<<endl;}
const double EPS= 1e-9 ;

/*  /////////////////////////     C o d i n g  S p a c e     /////////////////////////  */

const int MAXN= 80 + 9 ;
int a[MAXN];
string s;

int main()
{
    SI(o);
    while(o--)
    {
        cle(a,0);
        SI(s);
        int l=s.size();
        //这块要初始化0,否则会越界
        a[0]=(s[0]=='O');
        Rep(i,1,l-1)
        {
            if (s[i]=='O')
            {
                if (!a[i-1])
                a[i]++;
                else a[i]=a[i-1]+1;
            }
            else
            {
                a[i]=0;
            }
        }
        ll sum=0;
        rep(i,l) sum+=a[i];
        PI(sum);
    }

    return 0;
}

UVA 1586

这题告诉了我不可能全用cin,有的时候还是必须要用scanf的,还有函数isalpha(判断是否为英文) 和 isdigit(判断是否为数字) 能使代码更简洁,最后让你输出%.3f 就不能输出%f,那样会WA的。

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int INF=0x3f3f3f3f;
const ll LINF=0x3f3f3f3f3f3f3f3f;
#define PI(A) cout<<(A)<<endl
#define SI(N) cin>>(N)
#define SII(N,M) cin>>(N)>>(M)
#define cle(a,val) memset(a,(val),sizeof(a))
#define rep(i,b) for(int i=0;i<(b);i++)
#define Rep(i,a,b) for(int i=(a);i<=(b);i++)
#define reRep(i,a,b) for(int i=(a);i>=(b);i--)
#define dbg(x) cout <<#x<<" = "<<(x)<<endl
#define PIar(a,n) rep(i,n)cout<<a[i]<<" ";cout<<endl;
#define PIarr(a,n,m) rep(aa,n){rep(bb, m)cout<<a[aa][bb]<<" ";cout<<endl;}
const double EPS= 1e-9 ;

/*  /////////////////////////     C o d i n g  S p a c e     /////////////////////////  */

const int MAXN= 80 + 9 ;
int n;
string s;
bool us[MAXN];

int main()
{
    scanf("%d%*c",&n);
    while(n--)
    {
        cle(us,0);
        getline(cin,s);
        int l=s.size();
        map<char,int>mci;
        rep(i,l)
        {
            if (isalpha(s[i]))
            {
                mci[s[i]]++;
                us[i]=1;
            }
        }
        rep(i,l)
        {
            if (isdigit(s[i]))
            {
                int sum=0;
                if (i+1<l&&isdigit(s[i+1]))
                {
                    sum+=s[i+1]-'0';
                    sum+=(s[i]-'0')*10;
                }
                else
                    sum+=s[i]-'0';
                mci[s[i-1]]+=sum-1;
            }
        }
        double ans=12.01*mci['C']+1.008*mci['H']+16.00*mci['O']+14.01*mci['N'];
        printf("%.3f\n",ans);
    }
    return 0;
}

UVA 1225

数据范围小,纯模拟可A,但当时我在想,要用数学公式,搞了半天也没弄出来,坑 = =

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int INF=0x3f3f3f3f;
const ll LINF=0x3f3f3f3f3f3f3f3f;
#define cle(a,val) memset(a,(val),sizeof(a))
#define rep(i,b) for(int i=0;i<(b);i++)
#define dbg(x) cout <<#x<<" = "<<(x)<<endl
#define PIar(a,n) rep(i,n)cout<<a[i]<<" ";cout<<endl;
#define PIarr(a,n,m) rep(aa,n){rep(bb, m)cout<<a[aa][bb]<<" ";cout<<endl;}
const double EPS= 1e-9 ;

/*  /////////////////////////     C o d i n g  S p a c e     /////////////////////////  */

map<char,int>mci;
char s[10];
int sol(int n)
{
    int k=0;
    while(n>0)
    {
        s[k++]=n%10+'0';
        n/=10;
    }
    return k;
}
char biao[]={'0','1','2','3','4','5','6','7','8','9'};
int main()
{
    int o,n;
    scanf("%d",&o);
    while(o--)
    {
        mci.clear();
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            cle(s,0);
            int k=sol(i);
            for(int j=0;j<k;j++)
            {
                mci[s[j]]++;
            }
        }
        for(int i=0;i<10;i++)
        {
            printf("%d%c",mci[biao[i]],i==9?'\n':' ');
        }
    }
    return 0;
}

UVA 455

KMP大法好(PS:n-Next[n]不一定是最小循环节,只有当n%(n-Next[n])==0的时候,n-Next[n]才是最小循环节,当n-Next[n]!=0的时候,最小循环节是n >_< 又坑我半小时)

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int INF=0x3f3f3f3f;
const ll LINF=0x3f3f3f3f3f3f3f3f;
#define rep(i,b) for(int i=0;i<(b);i++)
#define cle(a,val) memset(a,(val),sizeof(a))
#define dbg(x) cout <<#x<<" = "<<(x)<<endl
#define PIar(a,n) rep(i,n)cout<<a[i]<<" ";cout<<endl;
#define PIarr(a,n,m) rep(aa,n){rep(bb, m)cout<<a[aa][bb]<<" ";cout<<endl;}
const double EPS= 1e-9 ;

/*  /////////////////////////     C o d i n g  S p a c e     /////////////////////////  */
const int MAXN= 100 + 9 ;
int Next[MAXN];
int len;
string x;
void kmp_pre()
{
    int i,j;
    j=Next[0]=-1;
    i=0;
    while(i<len)
    {
        while(-1!=j&&x[i]!=x[j])j=Next[j];
        Next[++i]=++j;
    }
}

int main()
{
    int o;
    cin>>o;
    while(o--)
    {
        cin>>x;
        len=x.size();
        kmp_pre();
        int d=len-Next[len];
        if (len%d==0)
        printf("%d\n",d);
        else printf("%d\n",len);
        if (o!=0) puts("");
    }
    return 0;
}

UVA 227

就是简单的模拟而已,但输入真的好特么麻烦 (⊙﹏⊙)

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int INF=0x3f3f3f3f;
const ll LINF=0x3f3f3f3f3f3f3f3f;
#define rep(i,b) for(int i=0;i<(b);i++)
#define cle(a,val) memset(a,(val),sizeof(a))
#define dbg(x) cout <<#x<<" = "<<(x)<<endl
#define PIar(a,n) rep(i,n)cout<<a[i]<<" ";cout<<endl;
#define PIarr(a,n,m) rep(aa,n){rep(bb, m)cout<<a[aa][bb]<<" ";cout<<endl;}
const double EPS= 1e-9 ;

/*  /////////////////////////     C o d i n g  S p a c e     /////////////////////////  */

const int MAXN= 10000 + 9 ;

char a[10][10];
char ope[MAXN];
int k=1;
int main()
{
    while(1)
    {
        gets(a[0]);
        if (a[0][0]=='Z') break;
        for(int i=1;i<5;i++)
        {
            gets(a[i]);
        }
        int cnt=0;
        while(scanf("%c",&ope[cnt])&&ope[cnt++]!='0') ;
        getchar();
        int x,y;
        rep(i,5)
        rep(j,5)
        if (a[i][j]==' ')
            x=i,y=j;
        bool out=0;
        for(int i=0;i<cnt;i++)
        {
            if (ope[i]=='A'){
                if (x-1>=0)
                    swap(a[x][y],a[x-1][y]),x-=1;
                else out=1;
            }
            if (ope[i]=='B'){
                if (x+1<5)
                    swap(a[x][y],a[x+1][y]),x+=1;
                else out=1;
            }
            if (ope[i]=='L'){
                if (y-1>=0)
                    swap(a[x][y],a[x][y-1]),y-=1;
                else out=1;
            }
            if (ope[i]=='R'){
                if (y+1<5)
                    swap(a[x][y],a[x][y+1]),y+=1;
                else out=1;
            }
        }
        if (k!=1)puts("");
        printf("Puzzle #%d:\n",k++);
        if (out) puts("This puzzle has no final configuration.");
        else
        {
            rep(i,5)
            rep(j,5)
            printf("%c%c",a[i][j],j==4?'\n':' ');
        }
    }
    return 0;
}

UVA 10340

输出™的打错了,调了20分钟,我去,下把输出就只复制

#include <bits/stdc++.h>
using namespace std;

#define PI(A) cout<<(A)<<endl
#define rep(i,b) for(int i=0;i<(b);i++)
const int MAXN= 100000 + 10000 ;
char s[MAXN],t[MAXN];

int main()
{
    while(scanf("%s%s",s,t)!=EOF){
        int ls=strlen(s),lt=strlen(t),cnt=0;
        rep(i,lt)
        if (s[cnt]==t[i]&&cnt<ls) cnt++;
        if (cnt==ls) puts("Yes");
        else puts("No");
    }
    return 0;
}

UVA 1587

这题真是坑死我了,不难的题,我却想了3小时,最后还是看别人代码才懂的,他说是长方体,那么正方体就是错的,只要根据长方体定义就好了,先判断6个面是不是两两相等,之后在看3个面是否有3条线相等,也就是是否能拼到一起

#include <bits/stdc++.h>
using namespace std;

struct rec {
    int l, w;
} r[6];
bool cmp(rec a, rec b) {
    return a.w < b.w || (a.w == b.w && a.l < b.l);
}

int main() {
    while(~scanf("%d%d", &r[0].w, &r[0].l)) {
        bool ok = 1;
        if(r[0].w > r[0].l) swap(r[0].w, r[0].l);
        for(int i = 1; i < 6; i++) {
            scanf("%d%d", &r[i].w, &r[i].l);
            if (r[i].w > r[i].l) swap(r[i].w, r[i].l);
        }
        sort(r, r + 6, cmp);
        for(int i = 0; i < 6; i += 2)
            if (r[i].w != r[i + 1].w || r[i].l != r[i + 1].l) ok = 0;
        if (r[0].w != r[2].w || r[0].l != r[4].w || r[2].l != r[4].l) ok = 0;
        puts(ok ? "POSSIBLE" : "IMPOSSIBLE");
    }
    return 0;
}