测试 3

本文解析了三道算法竞赛题目,包括去重复元素、国际象棋马走棋问题及期望DP问题。通过C++代码实现,涵盖了数据结构操作、搜索算法及动态规划等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

t1
del
去一个重,在特判一下

#include<cstdio>
#include<algorithm>
#include<cstdlib>
using namespace std;
int n,k,a[110000];

int main(){
    freopen("del.in","r",stdin);
    freopen("del.out","w",stdout);
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    sort(a+1,a+n+1);
    int ans=unique(a+1,a+n+1)-(a+1);
    if(n-ans>=k) printf("%d",ans);
    else printf("%d",n-k);

} 

t2
chess
简单的搜索题,递归模拟,没啥优化剪枝。。。
不知怎么搞的’,’忘加了。。
然后走一步的特判在程序里错了,弄出去就对了。。。

#include<cstdio>
#include<iostream>
using namespace std;
struct st{
    int maxn,cnt; 
};
int a[11][11],b[11][11];
int xx[]={1,1,-1,-1};
int yy[]={1,-1,-1,1};
int ans,ans2[11][11];
char s[19];
st dfs(int x,int y,int opt,int s){
    int tot=0,num=1;
    if(!s)
    {
        for(int i=0;i<4;i++)
        if(i!=opt)
        {
        if(x+xx[i]>10&&y+yy[i]>10&&y+yy[i]<=0&&x+xx[i]<=0)continue;
        if(a[x+xx[i]][y+yy[i]]==0) continue;
        if(a[x+xx[i]][y+yy[i]]==2&&x+xx[i]+xx[i]<=10&&y+yy[i]+yy[i]<=10&&y+2*yy[i]>0&&x+2*xx[i]>0&&a[x+xx[i]+xx[i]][y+yy[i]+yy[i]]==0){
            a[x+xx[i]][y+yy[i]]=0;
            st w=dfs(x+xx[i]+xx[i],y+yy[i]+yy[i],(i+2)%4,s);
            a[x+xx[i]][y+yy[i]]=2;
            if(w.maxn+1>tot){
                num=w.cnt;
                tot=w.maxn+1;
            }
            else if(w.maxn+1==tot) num+=w.cnt;
        }


        }
    }
    else
    for(int i=0;i<4;i++)
    if(i!=opt)
    {
        int t=1;
        while(x+t*xx[i]<=10&&y+t*yy[i]<=10&&y+t*yy[i]>0&&x+t*xx[i]>0&&!a[x+t*xx[i]][y+t*yy[i]]) t++;
        if(x+t*xx[i]>10&&y+t*yy[i]>10&&y+t*yy[i]<=0&&x+t*xx[i]<=0)continue;
        if(a[x+t*xx[i]][y+t*yy[i]]==1) continue;
        a[x+t*xx[i]][y+t*yy[i]]=0;
        int ww=t;
        t++;
        while(x+t*xx[i]<=10&&y+t*yy[i]<=10&&y+t*yy[i]>0&&x+t*xx[i]>0&&!a[x+t*xx[i]][y+t*yy[i]]){

            st w=dfs(x+t*xx[i],y+t*yy[i],(i+2)%4,s);

            if(w.maxn+1>tot){
                num=w.cnt;
                tot=w.maxn+1;
            }
            else if(w.maxn+1==tot) num+=w.cnt;
            t++;
        } 
        a[x+ww*xx[i]][y+ww*yy[i]]=2;
    }
    st tmp;
    tmp.maxn=tot;
    tmp.cnt=num;
    return tmp;
}
int num[11][11],num3,num4[11][11];
int main(){
    freopen("chess.in","r",stdin);
    freopen("chess.out","w",stdout);
    for(int i=1;i<=10;i++)  
    {
        cin>>s+1;
        for(int j=1;j<=10;j++)
        a[i][j]=s[j]-'0';
    }
    for(int i=1;i<=10;i++)
    {
        cin>>s+1;
        for(int j=1;j<=10;j++)
        b[i][j]=s[j]-'0';
    }

    //dfs(6,7,4,0);
    for(int i=1;i<=10;i++)
    for(int j=1;j<=10;j++)
    if(a[i][j]==1)
    {
            if(!b[i][j])
            {
                for(int k=2;k<4;k++)
                if(i+xx[k]<=10&&j+yy[k]<=10&&j+yy[k]>0&&i+xx[k]>0&&!a[i+xx[k]][j+yy[k]])
                num3++,num4[i][j]++;
            }
            else if(b[i][j]){
                for(int k=0;k<4;k++)
                {
                    int t=1;
                while(i+t*xx[k]<=10&&j+t*yy[k]<=10&&j+t*yy[k]>0&&i+t*xx[k]>0&&!a[i+t*xx[k]][j+t*yy[k]]) t++,num3++,num4[i][j]++;
                }

            }

            st w=dfs(i,j,4,b[i][j]);
        //printf("%d %d %d %d\n",i,j,w.maxn,w.cnt);
            if(w.maxn>ans){
                num[i][j]=w.cnt;
                ans2[i][j]=w.maxn;
                ans=w.maxn;
            }
            else if(w.maxn==ans) ans2[i][j]=w.maxn,num[i][j]+=w.cnt;

    }
    if(!ans){
        printf("%d\n",num3);
        for(int i=1;i<=10;i++)
        for(int j=1;j<=10;j++)
        if(num4[i][j])
        for(int k=1;k<=num4[i][j];k++)
        printf("(%d %d)\n",i,j);
    }
    else {
            int num2=0;
    for(int i=1;i<=10;i++)
    for(int j=1;j<=10;j++)
    if(ans==ans2[i][j])
     num2=num2+num[i][j];
    printf("%d\n",num2);
    for(int i=1;i<=10;i++)
    for(int j=1;j<=10;j++)
    if(ans==ans2[i][j])
    for(int k=1;k<=num[i][j];k++)
    printf("(%d %d)\n",i,j);
    }

}

t3
bonus
状压dp+期望。
dp[i][s]表示吃i个馅饼,s用二进制表示之前吃过哪些馅饼
倒着推,最后是零个馅饼

#include<cstdio>
#include<iostream>
using namespace std;
int k,n,need[1<<16],f;
double dp[109][1<<16],a[11999]; 
int main(){
    freopen("bonus.in", "r", stdin);
    freopen("bonus.out", "w", stdout);
    scanf("%d%d",&k,&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%lf",&a[i]);
        int x;
        scanf("%d",&x);
        while(x!=0){

            need[i]+=1<<(x-1);
            scanf("%d",&x);
        }
    }
    for(int i=k;i>=1;i--)
    for(int s=0;s<=(1<<n)-1;s++)
    {
        for(int j=1;j<=n;j++)
        {

        if((s&need[j])==need[j]) 
        dp[i][s]+=max(dp[i+1][s|(1<<j-1)]+a[j],dp[i+1][s]);
        else dp[i][s]+=dp[i+1][s];

       }
       dp[i][s]/=(double)n;
    }


    printf("%.6lf",dp[1][0]);
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值