CSP2022年刷题

202212-1

在这里插入图片描述
关键点: 只需要知道,第K年的x元的当前价值即可。
在这里插入图片描述

#include<iostream>
using namespace std; 
int n;
double i;  
double a[55];

int main()
{
	cin>>n>>i;
	double sum;
	double x;
	for(int j=0; j<=n;j++)
	{
		scanf("%lf", &x);
		a[j]=x;
	}
	for(int j=0;j<=n;j++)
	{
		for(int s=0;s<j;s++)
		{
			a[j]=a[j]/(1+i);  
		} 
		cout<<a[j]<<endl;           
	}
	for(int j=0; j<=n;j++)
	{
		sum+=a[j];
	}
	cout<<sum<<endl;
	return 0;
}

202212-2

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

#include<iostream>
using namespace std; 
int n,m;
int a[370];
int b[370];
int e[370];
int w[370];
int y[370];
int main()
{
	cin>>n>>m;
	for(int i=1;i<=m;i++)
	{
		cin>>a[i];
	}
	for(int i=1;i<=m;i++)
	{
		cin>>b[i];
	}
	for(int i=1;i<=m;i++)
	{
		int temp=i; 
		while(a[temp])
		{
			e[i]+=b[a[temp]];
			temp=a[temp];
		}
		e[i]+=1;
	}
	
	for(int i=1;i<=m;i++)
	{
		cout<<e[i]<<" ";
	}
	cout<<endl;

	return 0;
}
/*
10 5
0 1 0 3 2
1 2 1 5 2
*/

2022-9-1

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#include<iostream>
using namespace std; 
int n;
int a[21];
long long c[21]; 
long long d[22];
long long m;

int main()
{
	cin >> n >> m ;
	for( int i=1 ; i <= n ; i++ )
	{
		cin >> a[i] ;
	}
	c[0] = 1 ;
	for( int i=1 ; i<=n ; i++ )
	{
		c[i]=c[i-1]*a[i] ;
		d[i]=c[i];
	}
	d[0]=0;
	int cb=0;
	for(int i=1;i<=n;i++)
	{
		if(d[i-1]==0)
		{
			cout << m % d[i]/c[0] << " " ;
		}
		else
		{
			cb  = m % d[i] - m % d[i-1];
			cb= cb / c[i-1];
			cout << cb << " " ;
		}
	}
	return 0;
}

在这里插入图片描述

2022-9-2 何以包邮

在这里插入图片描述
第一种思路:
暴力
每一种书有两种选择, 选和不选。
n本书就有 2^n 种选择。只需要把所有可能的情况记录下来,不断更新最小的最接近x的值就行了。这样可以拿到70分。
这样可以用二进制数来枚举。
每一位代表选或者不选。 0 表 示 选 , 1 表 示 不 选 。

二进制枚举法很重要。。呜呜呜,又忘记了。 其实学过一遍来着

if(i<<j&1)  //  意思是如果 数字i  的  第 j  位 是1 的话, 则执行if里面的语句
第一种:70分的解法

用二进制完成

#include<iostream>
#include<algorithm>
using namespace std; 
int n;
int a[35];
int  m;
int main()
{
	cin >> n >> m ;
	for( int i=0 ; i < n ; i++ )
	{
		cin >> a[i] ;
	}
	int res=1e8;
	for(int i=0; i <  1<<n;  i++)  // i< 2^(n) 
	{
		int sum =0 ;  //sum 会每次都更新一遍的。 
		for(int j =0; j<n;j++)
		{
			if( i>>j & 1)
			{
				sum+=a[j];  //1 表示被选 
			}
			if(sum>=m)
			{
				res=min(res, sum); 
			}
		}
	}
	cout<<res<<endl;
	return 0;
}
第二种:70分的解法 暴力dfs搜索。
#include<iostream>
#include<algorithm>
using namespace std; 
int n;
int a[35];
int  m;
int res=1e8;
void  dfs(int u, int sum)
{
	if(u==n)
	{
		if(sum>=m)
		{
		     res= min(res, sum);	
		}
	}
	else
	{
		dfs(u+1, sum);  // 不选  
		dfs(u+1, sum+a[u]);  // 选 
	}
} 
int main()
{
	cin >> n >> m ;
	for( int i=0 ; i < n ; i++ )
	{
		cin >> a[i] ;
	}
	dfs(0,0);
	cout<<res<<endl;
	return 0;
}

在这里插入图片描述

100分思路 动态规划 dp

01 背包问题: 每一件物品只用一次。
完全背包问题:每一件物品可以用无限次。
多重背包: 每一件物品有无限个。
分组背包: 每一组里面只能选一个。

状态表示: f(i, j ) 集合( 一堆的选择方法 , 满足两个条件 。 ① 只从前 i 个物品中选, ② 选出的 物品的总体积 小于等于 j ) 和 属性 (最小值, 最大值,数量)。

f(i, j ) 表示选法的最大值。
f(N, v) 是答案。
状态计算:集合的划分。 不重复,不遗漏
在这里插入图片描述
分成包含第i 个物品的情况,和不包含第i 个物品的情况。
在这里插入图片描述
代码实现
在这里插入图片描述

逆向思维一下。选择n本书,在不超过sum-x的前提下, 越大越好。
在这里插入图片描述
从N个物品里面选择若干个物品,使得, 总体积不超过sum-x的情况下, 总价值最大。

#include<iostream>
#include<algorithm>
using namespace std; 
const int N=33, M=300010;
int w[N],f[M];
int x,n;
int main()
{
	cin >> n >> x ;
	int sum=0;
	for( int i=0 ; i < n ; i++ )
	{
		cin >> w[i] ;
		sum+=w[i];
	}
	int  m  = sum-x  ;  //背包的容量
	for(int i=0; i<n; i++)
    {
		for(int j=m  ; j>=w[i] ; j--)
		{
			f[j]  =  max( f[j]  , f[j-w[i]]+w[i]  ) ;
		 } 
	}
	cout << sum-f[m] << endl; // 总和  减去  f[m] 的 容量  
	return 0;
}

在这里插入图片描述

在这里插入图片描述

#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
int main(){
    int n[1001], sum;
    double over_a = 0;
    double d = 0;   
    cin >> sum;
    for(int i = 0; i < sum; i ++){
        cin >> n[i];
        over_a += n[i];
    }
    over_a = over_a / sum;

    for(int i = 0; i < sum; i ++){
        d += ((n[i] - over_a) * (n[i] - over_a));
    }
    d = d / sum;
    for(int i = 0; i < sum; i ++){
        printf("%.16f\n", (n[i] - over_a) / sqrt(d));
    }
    return 0;
}

寻宝!大冒险!

http://118.190.20.162/view.page?gpid=T147
在这里插入图片描述

#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const int L=1100,K=55;
int n,l,s;
int B[K][K];
int X[L],Y[L];

int main()
{
	cin>>n>>l>>s;
	for(int i=0;i<n;i++)
	{
		cin>>X[i]>>Y[i];
	}
	int x=0;
	int cnt=0;
    for(int i=s;i>=0;i--)
    {
    	for(int j=0;j<=s;j++)
    	{
    		cin>>x;
    		B[i][j]=x;
    		cnt+=B[i][j];
		}
	}
	int sum=0,res=0;
	for(int i=0 ; i < n ; i++)  //枚举 n 棵树 
    {
    	int sx = X[i]; int sy = Y[i];
    	sum=0;
    	if(sx+s>l || sy+s>l)
    	{
    		continue;
		}
    	for(int j=0 ; j <n ; j++)
    	{
    	    if(sx <= X[j] && X[j]-sx <=  s && Y[j]-sy <= s && Y[j]>=sy  )
    	    {
    	    	if(!B[X[j]-sx][Y[j]-sy])
    	    	{
    	    		sum=-1e8;
				}
				else
				{
					sum++;
				}
			}
    	}
    	if(sum==cnt)
    	{
    		res+=1;
		}
    }
	cout<<res<<endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值