2012天津regional的五道水题(ABCEH)

做virtual judge时的代码,感觉有点挫,随便贴一下吧,继续切博弈。

A题 模拟题

这题本身还是非常水的。写的时候要注意题意,队友读的题意我写了很久调不出来,最后慢慢读题了才一个个错误地改出来了。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <map>
using namespace std;
map<string,int>mp;
void init()
{
    mp["1m"]=1; mp["1s"]=11; mp["1p"]=21;
    mp["2m"]=2; mp["2s"]=12; mp["2p"]=22;
    mp["3m"]=3; mp["3s"]=13; mp["3p"]=23;
    mp["4m"]=4; mp["4s"]=14; mp["4p"]=24;
    mp["5m"]=5; mp["5s"]=15; mp["5p"]=25;
    mp["6m"]=6; mp["6s"]=16; mp["6p"]=26;
    mp["7m"]=7; mp["7s"]=17; mp["7p"]=27;
    mp["8m"]=8; mp["8s"]=18; mp["8p"]=28;
    mp["9m"]=9; mp["9s"]=19; mp["9p"]=29;
    mp["1c"]=31;mp["2c"]=32; mp["3c"]=33;
    mp["4c"]=34;mp["5c"]=35; mp["6c"]=36;
    mp["7c"]=37;
}
int cnt[40],arr[40],www[40];
bool isok()
{
    for(int i=0;i<40;i++) if(cnt[i]>4) return 0;
    return 1;
}
bool jud0()
{
    for(int i=1;i<38;i++) arr[i]=www[i];
    for(int i=1;i<38;i++)
    {
        if(arr[i]>=3) arr[i]-=3;
        if(arr[i])
        {
            if(i>30) return 0;//选顺子时不能在c类型里选择
            if(arr[i+1]<arr[i]||arr[i+2]<arr[i]) return 0;
            else arr[i+1]-=arr[i],arr[i+2]-=arr[i],arr[i]=0;
        }
    }
    return 1;
}
bool jud1()
{
    for(int i=1;i<38;i++) www[i]=cnt[i];
    for(int i=1;i<38;i++) if(www[i]>=2)//居然是要选择两个相同的
    {
        www[i]-=2;
        if(jud0())return 1;
        www[i]+=2;
    }
    return 0;
}
bool jud2()
{
    int ans=0;
    for(int i=0;i<40;i++) if(cnt[i]==2) ans++;
    return ans==7;
}
bool jud3()
{
    int a=0,b=0;
    if(cnt[1]==1)  a++; if(cnt[1]==2)  b++;
    if(cnt[9]==1)  a++; if(cnt[9]==2)  b++;
    if(cnt[11]==1) a++; if(cnt[11]==2) b++;
    if(cnt[19]==1) a++; if(cnt[19]==2) b++;
    if(cnt[21]==1) a++; if(cnt[21]==2) b++;
    if(cnt[29]==1) a++; if(cnt[29]==2) b++;

    for(int i=31;i<38;i++)//居然可以在c类型中选择 
    {
        if(cnt[i]==1) a++;
        if(cnt[i]==2) b++;
    }
    return a==12&&b==1;
}
void out(int x)
{
    putchar(' ');
    putchar(x%10+48);
    if(x<10) putchar('m');
    else if(x<20) putchar('s');
    else if(x<30) putchar('p');
    else putchar('c');
}
int main()
{
    //freopen("in","r",stdin);
    int t=1;init();
    scanf("%d",&t);
    while(t--)
    {
        memset(cnt,0,sizeof(cnt));
        char s[10];
        for(int i=0;i<13;i++)
        {
            scanf("%s",s);
            cnt[mp[s]]++;
        }
        bool fg;
        vector<int>ans;
        for(int i=1;i<38;i++)
        {
            if(i==10||i==20||i==30) continue;
            cnt[i]++;fg=isok();
            if(!fg){cnt[i]--; continue;}
            if(jud3()||jud2()||jud1()) ans.push_back(i);
            cnt[i]--;
        }
        if(ans.size())
        {
            sort(ans.begin(),ans.end());
            printf("%d",ans.size());
            for(int i=0;i<ans.size();i++) out(ans[i]);puts("");
        }
        else puts("Nooten");
    }
    return 0;
}

B题 数论水题

根号N枚举出因子计算一下。

#include<iostream>
using namespace std;
typedef long long ll;

ll g(ll x,ll m)
{
    ll ans=0;
    while(x)
    {
        ll tmp=x%m;
        ans+=tmp*tmp;
        x/=m;
    }
    return ans;
}

void out(ll x,ll m)
{
    char s[20];
    int i=19;s[i]=0;
    while(x)
    {
        int tmp=x%m;
        s[--i]=tmp<10?tmp+48:tmp+65-10;
        x/=m;
    }
    cout<<s+i<<endl;
}
int main()
{
    ll n,m;
    while(cin>>n>>m)
    {
        ll ans=0;
        for(ll i=1;i*i<=n;i++) if(n%i==0)
        {
            ans+=g(i,m);
            if(i*i!=n) ans+=g(n/i,m);
        }
        out(ans,m);
    }
    return 0;
}

C题 DP题

注意向上旋转的情况的转移。dp[i][j][k]表示前i位相同且第i+1位增加为j ,i+2位增加为k的状态 对应的最小转动次数。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

int dp[1111][11][11];
char a[1111],b[1111];

int main()
{
    while(scanf("%s%s",a,b)!=EOF)
    {
        memset(dp,63,sizeof(dp));
        dp[0][0][0]=0;
        int n=strlen(a);
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<10;j++)
            {
                for(int k=0;k<10;k++)
                {
                    int tmp=((b[i]-a[i]-j)%10+10)%10;
                    for(int p=0;p<=tmp;p++)
                    {
                        for(int q=0;q<=p;q++)
                        {
                            dp[i+1][(k+p)%10][q]=min(dp[i+1][(k+p)%10][q],dp[i][j][k]+tmp);
                        }
                    }
                    tmp=10-tmp;
                    for(int p=0;p<=tmp;p++)
                    {
                        for(int q=0;q<=p;q++)
                        {
                            dp[i+1][((k-p)%10+10)%10][(10-q)%10]=min(dp[i+1][((k-p)%10+10)%10][(10-q)%10],dp[i][j][k]+tmp);
                        }
                    }
                }
            }
        }
        printf("%d\n",dp[n][0][0]);
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
    }
    return 0;
}

E题 图论题

 从n-1到1枚举判断(建图判连通)是否能不选,输出选择的结果。做VJ时将队友的贪心卡了整场,快结果时我来写又写晕了.....

#include<cstdio>
#include<cmath>
#include<cstring>
int n,d;

int x[1111],y[1111];
int dis(int i,int j)
{
    return ceil(sqrt(0.0+(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])));
}
char ans[1111];
int top;
bool vis[1111],use[1111];
int ev[111111],nxt[111111],head[1111],e;
void add(int u,int v)
{
    //printf("%d %d\n",u,v);
    ev[e]=v,nxt[e]=head[u];head[u]=e++;
}

void dfs(int u,int p)
{
    vis[u]=1;
    for(int i=head[u];~i;i=nxt[i])
    {
        int v=ev[i];
        if(vis[v]) continue;
        dfs(v,u);
    }
}
int idx;
bool solve()
{
    memset(vis,0,sizeof(vis));
    dfs(0,0);
    for(int i=1;i<n;i++) if(!vis[i]) return 0;
    for(int i=n-1;i;i--)
    {
        use[i]=0;
        memset(head,-1,sizeof(head));e=0;
        for(int i=0;i<n;i++) for(int j=i+1;j<n;j++)
        {
            if(use[i]&&use[j]&&dis(i,j)<=d) add(i,j),add(j,i);
            if(!use[i]&&!use[j]) continue;
            if(!use[i]||!use[j]) if(dis(i,j)*2<=d) add(i,j),add(j,i);
        }
        memset(vis,0,sizeof(vis));
        dfs(0,0);int need=0;
        for(int j=0;j<n;j++) if(!vis[j]) need=1;
        use[i]=need;
    }
    for(int i=n-1;~i;i--) ans[top++]=use[i]+48;
    ans[top]=0;
    idx=0;
    while(ans[idx]==48) idx++;
    return 1;
}
int main()
{
    //freopen("in.txt","r",stdin);
    while(scanf("%d%d",&n,&d)!=EOF)
    {
        e=top=0;
        memset(use,1,sizeof(use));
        memset(head,-1,sizeof(head));
        use[0]=1;
        for(int i=0;i<n;i++) scanf("%d%d",&x[i],&y[i]);
        for(int i=0;i<n;i++) for(int j=i+1;j<n;j++) if(dis(i,j)<=d) add(i,j),add(j,i);
        if(solve()) puts(ans+idx);
        else puts("-1");
    }
    return 0;
}

H题 什么都不是的水题

#include<cstdio>

int t,x,y;
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        double x,y,p,q;
        scanf("%lf%lf%lf%lf",&x,&y,&p,&q);
        double ans1=q*p*(x+y)+(1-q)*x;
        double ans2=q*y+(1-q)*p*(x+y);
        if(ans1>ans2) printf("tiger %.4lf\n",ans1);
        else printf("wolf %.4lf\n",ans2);
    }
    return 0;
}



展开阅读全文

没有更多推荐了,返回首页