5.30题解

5.30题解

第一题
5.30题解_第1张图片

第一天1x1,第二天2x2,累加到n跳出循环,数据很小也不用多想直接输出。

#include
using namespace std;
int n,sum;
long long ans=0;
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=i;j++){
			ans+=i;
			sum++;
			if(sum==n) break;
		}
		if(sum==n) break;
	}
	cout<

第二题
5.30题解_第2张图片

广搜模板,8个方向建个数组搜索,如果3*3内有炸弹就加1。很久没有打了忘记搜了一个要标记,一直没结果,浪费很多时间。

#include
using namespace std;
int next[8][2]{{1,1},{-1,-1},{1,-1},{-1,1},{0,1},{1,0},{0,-1},{-1,0}};
char a[1000][1000],b[1000][1000];
bool dis[1000][1000];
int n,m;
void dfs(int x,int y){
	if(a[x][y]=='*') b[x][y]=a[x][y];
	if(x>n || y>m || x<0 || y<0 || dis[x][y]==1) return;
	for(int i=0;i<8;i++){
	    int fx=x;int fy=y;
		dis[fx][fy]=1;
		fx+=next[i][0];
		fy+=next[i][1];
		dfs(fx,fy);
		if(a[fx][fy]=='*' && a[x][y]!='*') {
			if(!b[x][y]) b[x][y]='1';
			else b[x][y]++;
	}
	
}}
int main(){
	//freopen("mine.in","r",stdin);
	//freopen("mine.out","w",stdout);
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cin>>a[i][j];
		}
	}	
	dfs(0,0);
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(b[i][j])cout<

第三题
5.30题解_第3张图片
这个题感觉是最难的一道。
先看第一个条件 x+z=2y,得出x+z为偶数,即x,z奇偶性质相同
再看第二个性质
(x+z)
(num[x]+num[z])=xnum[x]+xnum[z]+znum[x]+znum[z]
又因为x,z奇偶性质相同
所以可以化简为(i1num[i1]+i1num[i2]+i2num[i1]+i2num[i3])+(i1num[i1]+i1num[i3]+i3num[i1]+i3num[i3])…
再提出i1相同项,得到
i1*(num[i1]+num[i2]+…….+num[in])+n*(i1num[i1])
对于in
则是in
(num[i1]+num[i2]+…….+num[in])+n*(in*num[in])
再求和就是答案。

#include
using namespace std;
int n,c;
int sum[2][100001],num[100001],d[2][100001];
int col[100001];
long long maxx;
int main()
{
    cin>>n>>c;
    for (int i=1;i<=n;i++)
    {
        cin>>num[i];
        num[i]%=10007;    
    }
    for (int i=1;i<=n;i++)
    {
        cin>>col[i];
        sum[i%2][col[i]]+=num[i];    
        sum[i%2][col[i]]%=10007;
        d[i%2][col[i]]++;        
    }
    for (int i=1;i<=n;i++)
    {
        maxx+=i%10007*((sum[i%2][col[i]]+(d[i%2][col[i]]-2)%10007*num[i])%10007);
        maxx%=10007;        
    }
    cout<

第四题
5.30题解_第4张图片

我本来是准备直接混点分的,没想到还能ac。代码只适用于每次的第一个用户不变的情况,也就是疲劳值的最大值小于最大路程的两倍的情况,如果存在有一个用户的推销疲劳值极大就不对了。

#include
using namespace std;
int dp[100001],a[100001],b[10001],n,t,st,k,flag;
int main(){
	//freopen("salesman.in","r",stdin);
	//freopen("salesman.out","w",stdout);
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	for(int i=1;i<=n;i++){
		cin>>b[i];
	}
	for(int i=1;i<=n;i++){
		if(dp[1]<2*a[i]+b[i]){
			dp[1]=2*a[i]+b[i];
			st=i;
		}
	}
	dp[n]+=b[st];
	b[st]=0;
	sort(b+1,b+1+n);
	cout<

正确代码应该是
我们先把数组排序
用sum[i]表示a数组的前i项的和,q[i]表示s数组的前i项的最大值,h[i]表示a[i]2+s[i]后i项的最大值,对于每个x,他的答案就是max(sum[x]+2q[x],sum[x-1]+h[x])

#include
#include
#include
using namespace std;
struct home{
    int s,v;
}a[100010];
int q[100010];
int h[100010],qm[100010];
int n;
bool cmp(home a,home b)
{
    return a.v>b.v;
}
int main()
{
    scanf("%d",&n);
    for (int i=1;i<=n;i++)
    {
        scanf("%d",&a[i].s);
    }
    for (int i=1;i<=n;i++)
    {
        scanf("%d",&a[i].v);
    }
    sort(a+1,a+1+n,cmp);
    for (int i=n;i>=1;i--)
    {
        h[i]=max(h[i+1],2*a[i].s+a[i].v);
    }
    for (int i=1;i<=n;i++)
    {
        qm[i]=max(qm[i-1],a[i].s);
    }
    for (int i=1;i<=n;i++)
        q[i]=q[i-1]+a[i].v;
    for (int i=1;i<=n;i++)
    {
        printf("%d\n",max(q[i-1]+h[i],q[i]+2*qm[i]));
    }
} 

你可能感兴趣的:(5.30题解)