NOIP Is Coming 1(NOIP模拟赛)/省选专练之SCOI2005骑士



怪米怪眼的题

#include<bits/stdc++.h>
using namespace std;
const int N=101;
int n,m,p,q;
struct Node{
	int n,m;
	double b;
}Basic[N],Update[N];
double dp[51][51]={};
int main(){
	freopen("equipment1.in","r",stdin);
//	freopen("equipment.out","w",stdout);
	scanf("%d%d%d%d",&n,&m,&p,&q);
	for(int i=1;i<=p;i++){
		scanf("%d%d%lf",&Basic[i].n,&Basic[i].m,&Basic[i].b);
	}
	for(int i=1;i<=q;i++){
		scanf("%d%d%lf",&Update[i].n,&Update[i].m,&Update[i].b);
	}
//	memset(dp,-1,sizeof(dp));
	for(int i=0;i<=n;i++){
		for(int j=0;j<=m;j++){
			dp[i][j]=0;
		}
	}
	dp[0][0]=0;
	for(int i=1;i<=p;i++){
//		cout<<Basic[i].b<<'\n';
		for(int j=Basic[i].n;j<=n;j++){
			for(int k=Basic[i].m;k<=m;k++){
				dp[j][k]=max(dp[j-Basic[i].n][k-Basic[i].m]+Basic[i].b,dp[j][k]);
			}
		}
	}
	for(int i=1;i<=q;i++){
//		cout<<Update[i].b<<'\n';
		for(int j=Update[i].n;j<=n;j++){
			for(int k=Update[i].m;k<=m;k++){
				dp[j][k]=max(dp[j][k],dp[j-Update[i].n][k-Update[i].m]*Update[i].b);
			}
		}
	}
	double ans=-1;
	for(int i=0;i<=n;i++){
		for(int j=0;j<=m;j++)
//			if(dp[i][j]>-1)
//			cout<<dp[i][j]<<" ";
//			else cout<<-1<<" ";
			ans=max(ans,dp[i][j]);
//		}
//		cout<<'\n';
	}
//	cout<<dp[5][10];
	printf("%.9lf",ans);
	return 0;
}
#include<bits/stdc++.h>
using namespace std;
double sum[2][101]={};
int A[101][101]={};
int k[101]={};
int n,m;
int main(){
	freopen("C2.txt","r",stdin);
//	freopen("cocktail.in","r",stdin);
//	freopen("cocktail.out","w",stdout);
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		scanf("%lf",&sum[0][i]);
	}
//	for(int i=1;i<=n;i++){
//		printf("%.2lf ",sum[0][i]);
//	}
//	cout<<"-====-"<<'\n';
	for(int i=1;i<=n;i++){
		scanf("%d",&k[i]);
		for(int j=1;j<=k[i];j++){
			scanf("%d",&A[i][j]);
		}
		k[i]++;
		A[i][k[i]]=i;
	}
	for(int i=1;i<=min(m,300);i++){
		int cur=i%2;
//		cout<<"cur = "<<cur<<'\n';
		for(int j=1;j<=n;j++)sum[cur][j]=0;
		for(int ii=1;ii<=n;ii++)
			for(int j=1;j<=k[ii];j++){
				sum[cur][A[ii][j]]+=sum[(i+1)%2][ii]/(double)k[ii]*1.0;
		 	}
		for(int j=1;j<=n;j++){
			printf("%.4lf\n",sum[cur][j]);
		}	
		cout<<'\n';	
	}
	for(int i=1;i<=n;i++){
		if(m<300)
		printf("%.4lf\n",sum[m%2][i]);
		else printf("%.4lf\n",sum[1][i]);
	}
	return 0;
}

#include<iostream>
#include<cstdio>
#define f(i,a,b)  for(i=a;i<=b;++i)
using namespace std;
int a[6][6];
int b[6][6];//={{},
            /*{0,1,1,1,1,1},
            {0,0,1,1,1,1},
            {0,0,0,-1,1,1},
            {0,0,0,0,0,1},
            {0,0,0,0,0,0}};//打个表方便之后判断;*/
int dx[8]={-2,-2,-1,1,-1,1,2,2};
int dy[8]={-1,1,2, 2,-2,-2,-1,1};//顺序很重要,等下可以知道;
int mxd;//maxdeep最大深度
int Goal;
int check(int k,int x,int y,int sum,int la)
{
 //   printf("%d\n",sum);
    if(k+sum>mxd)return 0;//如果超过限制,直接返回0
    if(sum==0)return 1;//全部归位,返回1
    int i,xx,yy,p;
    bool fl=0,fll=0;
    f(i,0,7)
    {
        if(i!=(7-la))//就是这里,7-la就是上一次移动的反方向,防止移回去导致死递归
        {
            xx=x+dx[i];yy=y+dy[i];
            p=sum;//sum是当前未归位数,用p存出来方便修改
            if(xx<=5&&xx>0&&yy<=5&&yy>0)
            {
                if(a[xx][yy]==b[xx][yy]&&a[xx][yy]!=b[x][y])++p;
                if(a[xx][yy]!=b[xx][yy]&&a[xx][yy]==b[x][y])--p;
                if(b[xx][yy]==-1)--p;
                if(b[x][y]==-1)++p;//四种情况判断
                a[xx][yy]^=a[x][y],a[x][y]^=a[xx][yy],a[xx][yy]^=a[x][y];
                fl=check(k+1,xx,yy,p,i);//不能直接返回check的值,只有1才返回;
                if(fl)return 1;
                a[xx][yy]^=a[x][y],a[x][y]^=a[xx][yy],a[xx][yy]^=a[x][y];
            }
        }
    }
    return 0;//都不行,返回0;
}
int main()
{
	freopen("knight.in","r",stdin);
	freopen("knight.out","w",stdout);
    int i,j,t;
    char k;
    scanf("%d%d",&t,&Goal);
	for(int i=1;i<=5;i++){
		char s[11];
		scanf("%s",s);
		for(int j=0;j<5;j++){
			if(s[j]=='1'){
				b[i][j+1]=1;
			}
			if(s[j]=='2'){
				b[i][j+1]=0;
			}
			if(s[j]=='*'){
				b[i][j+1]=-1;
			}
		}
	}
    while(t--)
    {
        int mn=0,x,y;
        f(i,1,5)
        f(j,1,5)
        {
            cin>>k;
            if(k=='*')
            {
                a[i][j]=-1;
                x=i;y=j;
            }
            else a[i][j]=k-'0';
            if(a[i][j]!=b[i][j])mn++;//mn是深度最低的,有一个不同就加1,因为归位这个至少1次操作
        }
        int Just=1;
        for(int i=1;i<=5;i++){
        	for(int j=1;j<=5;j++){
        		if(a[i][j]!=b[i][j]){
        			Just=0;
        			break;
        		}
        	}
        }
        if(Just==1){
        	puts("0");
        	continue;
        }
        bool fl=0;
       // printf("%d\n",mn);
        f(i,mn,Goal+1)
        {
            mxd=i;
            if(check(0,x,y,mn,-1))
            {           	
                printf("%d\n",i-1),fl=1;break;
            }
        }
        if(!fl)
        	printf("-1\n");
//        t--;
    }
    return 0;
}


猜你喜欢

转载自blog.csdn.net/fcb_x/article/details/81022818