“山大地纬杯”第十二届山东省ICPC大学生程序设计竞赛(正式赛)

A Seventeen

题目大意:给定一个数,用1~n的每个数,使用+ - * ( )运算符号,每个数仅可以使用一次,使其结果为17, 这个组合有很多个,任意写出一个,如果找不到这样的组合数,输出-1。
思路:如1 2 3 4 一样,1-2-3+4=0,四个数为一个循环,只找到开头的四个数,剩下的循环即可,分析可知:1~3找不到这样的组合数,输出-1,开头的四个数为4 5 6 7。
代码:

#include<bits/stdc++.h>
using namespace std;
int n;
int main()
{
	cin>>n;
	if(n>=1&&n<=3)
		cout<<"-1";
	else 
	{
		int t=n%4;
		if(t==0)
		{
			if(n==4)
				cout<<"3*(1+4)+2";
			else
				cout<<"3*(1+4)+2"<<'+';
			for(int i=5;i<=n;i++)
			{
				if(i%4==1) cout<<i<<'-';
				else if(i%4==2) cout<<i<<'-';
				else if(i%4==3) cout<<i<<'+';
				else 
				{
					if(i==n) cout<<i;
					else  cout<<i<<'+';
				}
			}
		}
		else if(t==1)
		{
			if(n==5)
				cout<<"(2-1)*3*4+5";
			else
				cout<<"(2-1)*3*4+5"<<'+';
			for(int i=6;i<=n;i++)
			{
				if(i%4==2) cout<<i<<'-';
				else if(i%4==3) cout<<i<<'-';
				else if(i%4==0) cout<<i<<'+';
				else 
				{
					if(i==n) cout<<i;
					else  cout<<i<<'+';
				}
			}
		}
		else if(t==2)
		{
			if(n==6)
				cout<<"1-2-3*4+5*6";
			else
				cout<<"1-2-3*4+5*6"<<'+';
			for(int i=7;i<=n;i++)
			{
				if(i%4==3) cout<<i<<'-';
				else if(i%4==0) cout<<i<<'-';
				else if(i%4==1) cout<<i<<'+';
				else 
				{
					if(i==n) cout<<i;
					else  cout<<i<<'+';
				}
			}
		}
		else if(t==3)
		{
			if(n==7)
				cout<<"-1*(2+3)-4*5+6*7";
			else
				cout<<"-1*(2+3)-4*5+6*7"<<'+';
			for(int i=8;i<=n;i++)
			{
				if(i%4==0) cout<<i<<'-';
				else if(i%4==1) cout<<i<<'-';
				else if(i%4==2) cout<<i<<'+';
				else 
				{
					if(i==n) cout<<i;
					else  cout<<i<<'+';
				}
			}
		}
	}
	return 0;
}

E Subsegments


题目大意:给定数n x;接下来输入n个数,将数组中的数按照次序相乘,找到其积为x的值,求这样的组合数符合条件的一共有多少个。
思路:可以将两种情况进行分析,即存在0和不存在0两种情况。
代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=998244353;
const int N=5e5+10;
ll a[N],n,x,ans=0,sum=1;
int main()
{
	cin>>n>>x;
	for(int i=1;i<=n;i++) 
		cin>>a[i];
	//有两种可能性,x=0,x!=0;
	if(x==0) 
	{
		int last=0;
		for(int i=1;i<=n;i++)
		if(a[i]==0)
		{
			ans+=(i-last)*(n-i+1);
			last=i;
		}
		cout<<ans;
	}
	else
	{
		map<int,int>heap;//维护;
		heap[x]=1;
		for(int i=1;i<=n;i++)
		{
			if(a[i]!=0)
			{
				sum=sum*a[i]%mod;
				ans+=heap[sum];
				heap[sum*x%mod]++;
			}
			else
			{
				sum=1;
				heap.clear();
				heap[x]=1;	
			}	
		}
		cout<<ans;
	}
	return 0;
}

K Coins


题目大意:给定硬币的额度,给定一个数,看A B哪个用的查询的答案是获取该值所需的最小硬币数‎,如果无法获得该值,则答案为−1‎.‎‎如果它们都可以获得最小数字,则输出‎‎“both”
思路:由已知条件可知,当给定数字大于两人硬币最大额度乘积时,明显是A的硬币数出的最少。
代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 13*19+10;
int c1[5] = {0,2,3,17,19};
int c2[5] = {0,5,7,11,13};
int f[N],g[N];
int main()
{
	memset(f,0x3f,sizeof f);
	memset(g,0x3f,sizeof g);
	f[0] = 0;
	g[0] = 0;
	for(int i = 1;i<=4;i++)
	{
		for(int j = c1[i];j<N;j++)
			f[j] = min(f[j-c1[i]]+1,f[j]);
		for(int j = c2[i];j<N;j++)
			g[j] = min(g[j-c2[i]]+1,g[j]);
	}
	int q;
	cin>>q;
	while(q--)
	{
		int x;
		scanf("%d",&x);
		if(x==1) 
			puts("-1");
		else if(x>=N) 
			puts("A");
		else
		{
			if(f[x]==g[x])
				puts("both");
			else if(f[x]<g[x]) 
				puts("A");
			else 
				puts("B");
		}
	}
	return 0;
}

**

H Counting

**
题目大意:在一张 n × m 的网格图上,给定 k 个人在 0 ∼ T 秒内的行动路
线(每秒只能走一步),求每秒重叠的人的对数。
思路:对于网格图的每一个位置维护,根据每一个人的移动情况修改,同时维护答案。
代码:

#include<bits/stdc++.h>
using namespace std;
const int N=3e3+10;
int mp[N][N],x[N],y[N];
char s[N][N];
int n,m,k,t;
int main()
{
	cin>>n>>m>>k>>t;
	for(int i=1;i<=k;i++)
	{
		scanf("%d %d",&x[i],&y[i]);
	}
	for(int i=1;i<=k;i++)
	{
		cin>>s[i];
	}
	for(int i=0;i<=t;i++)
	{
		int ans=0;
		for(int j=1;j<=k;j++)
		{
			ans=ans+mp[x[j]][y[j]];
			mp[x[j]][y[j]]++;
		}
		cout<<ans<<endl;
		if(i==t) break;
		for(int j=1;j<=k;j++)
		{
			mp[x[j]][y[j]]=0;
			if(s[j][i]=='L') y[j]--;
			if(s[j][i]=='R') y[j]++;
			if(s[j][i]=='U') x[j]--;
			if(s[j][i]=='D') x[j]++;
		}
	}
	return 0;
}

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值