“Shopee杯” e起来编程暨武汉大学2020年大学生程序设计大赛决赛(重现赛)

比赛链接

文章目录

  • A题 A Simple Problem about election
    • 题目描述
    • 题解:
    • 代码:
  • D题 Deploy the medical team
    • 题意:
    • 题解:
    • 代码:
  • F题 Figure out the sequence
    • 题意:
    • 题解:
    • 代码

A题 A Simple Problem about election

链接:

题目描述

n名候选人,每个人必须提名其中m个人,(也可以提名自己),候选人将按照获得的提名降序排列,如果数量相同则按照名字字典序递增排列。
每个人也是按照名字依次提名m人,
叫ZZZZSGW的这个人感觉自己太倒霉了,(名字这么多z,每次提名),他最后提名,问还能不能让自己获得最高地位?

样例:
输入

2
5 3
5 1 2 6 7
5 3
5 1 2 5 7

输出

3
2

题解:

自己肯定还是要给的,然后剩下的m-1个票就要尽可能与自己票数相差大的人(也就是不对自己的排名造成影响),有两种情况,一个是比自己票多的,还有个是被投一票也赶不上自己的
但是如果票过多,就只能被迫给剩下的人投票
贪心即可
详细见代码

代码:

#include
#define forr(n) for(int i=1;i<=n;i++)
using namespace std;
const int maxn=1e5+7;
int a[maxn]; 
int main(){
    int T,ans=0;;
    cin>>T;
	while(T--)
	{
        int n,m;
        
		scanf("%d%d",&n,&m);
        
		forr(n)cin>>a[i];
        
        int w=++a[1];//先给自己投票 
        int q=m;
		--q;//投完自己,投票次数少一个 
        if(q==0);
        else 
		{
            for(int i=2;i<=n;++i)
			{
                if(a[i]>=w)//如果票比他多 
				{
                    ++a[i];
					--q;
                }
				else if(a[i]+1<w)//如果这个人投一票也赶不上 
				{
                    ++a[i];
					--q;
                }
                if(!q)//如果都投完退出 
				{
                    break;
                }
            }
        }

        for(n)
		{
			if(a[i]>=a[1])ans++;
        }//全部投完票后看看自己排第几名 
        cout<<ans+q<<endl;//如果还有余票 
    }
    return 0;
}

D题 Deploy the medical team

链接:

题目描述

The outbreak of the COVID-19 has infected more than 50,000 people in
Wuhan and nearly 70,000 people in Hubei province, which brings on
great pressure on the local hospital and medical workers. To help the
people in Hubei defeating the virus and returning to normal life as
soon as possible, many other province deployed their medical teams to
Hubei and offered lots of help.

Now it’s the time for a hospital in Bitland to choose who will be sent
to join this great mission. There are nn medical workers in the
hospital ready to deploy and you can send arbitrary numbers of persons
to the team. Also, a medical team need a captain in charge of all the
work, so once we confirm the people in the team, we need to set one of
them as captain too. However, being a captain needs a lot experience,
so there are only mm people capable with the responsibility of a
captain. Therefore, A team cannot be made up of people without someone
that can be the captain.

And here’s the question: How many ways are there to pick up a medical
team with a captain? Notice that two teams are consider different as
long as they have different participants or have different captain.

Also, due to the large memory of Bitland, the number of workers in
hospital can be as large as 109 ! And that means your answer can be
very large, so please output the result of the answer modulo 109+7

输入描述:

The input consists of multiple test cases. The first line of the input
contains an integer T — the number of the test cases.

For each test cases, there will be two integers nn,mm separated by
space in one line, which means the number of workers in hospital and
the numbers of people who can be the captain. Here 0≤m≤n≤109 .

输出描述:

For each test case, output a single integer ansans in a line, denoting
the answer modulo 109+7

示例1
输入

3
3 3
5 4
2 1

输出

12
64
2

题意:

一共n个人,m个人可以当队长,每个队只能有一个队长,也必须有一个队长,问组队方法?
(最讨厌英语题了)

题解:

组合数问题
先从m人中选一个队长,剩下n-1个人任选即可
C0n-1+C1n-1+C2n-1…+Cn-1n-1=2n-1
sum=m*2n-1

代码:

#include
using namespace std;
typedef long long ll;
const int mod=1e9+7;
ll qpow(ll a, ll b) 
{
  ll ans = 1;
  while(b) 
  {
    if(b & 1) ans = ans * a % mod;
    a = a * a % mod;
    b >>= 1;
  }
  return ans;
}
int T;
ll n, m;
int main() {
 
 	 cin >> T;
	  while(T--) 
	  {
	    cin >> n >> m;
	    printf("%lld\n",m * qpow(2, n - 1) % mod );
	  }
  return 0;
}

F题 Figure out the sequence

题意:

两个字符串,一次叠加,问你n轮后,每个字母出现个数

样例:
链接:https://ac.nowcoder.com/acm/contest/5523/F
来源:牛客网

输入

Abc
def
4

输出

A: 1
b: 1
c: 1
d: 2
e: 2
f: 2

根据样例输入我们可以都到每轮叠加后的串
“Shopee杯” e起来编程暨武汉大学2020年大学生程序设计大赛决赛(重现赛)_第1张图片
n=4时就是 defabcdef
分别统计每个字母的个数

题解:

dp
我们可以看出要求第n轮,就是第n-1轮加n-2轮
因为问的是个数,所以不用管顺序递推就可以
f[i][j]表示第i个字符串中字母j出现的次数(此处j为int型对应的是char型的字符)
得到递推式:f [ i ] [ j ] = f[ i - 1 ] [ j ]+ f [ i -2 ] [ j ]
我们一开始将读入的s1和s2进行预处理
也就是先给f[1][j]与f[2][j]赋值
具体可以看代码:

代码

#include
#define forr(i,n) for(int i=0;i
using namespace std;
typedef long long ll;
const int maxn=1e5+7;
ll f[maxn][1000]; 
inline ll read()
{
	ll s=0,w=1;
	char ch=getchar();
	while(ch<48||ch>57){if(ch=='-')w=-1;ch=getchar();}
	while(ch>=48&&ch<=57)s=(s<<1)+(s<<3)+(ch^48),ch=getchar();
	return s*w;
}
int main()
{
	string s1,s2;
	int n;

	cin>>s1>>s2;
		n=read();
	forr(i,s1.size())
	{
		int w=(int)s1[i];
		f[1][w]++;
//		printf("%c %lld\n",w,f[1][w]);
	}
	
		forr(i,s2.size())
	{
		int w=(int)s2[i];
		f[2][w]++;
	}
	for(int i=3;i<=n;i++)
	{
		forr(j,300)
		{
			f[i][j]=f[i-1][j]+f[i-2][j];
		}
	}
	forr(j,300)
	{
		if(f[n][j])
		printf("%c: %lld\n",j,f[n][j]);
	}
	return 0;
  
}
//“defabcdef”

你可能感兴趣的:(“Shopee杯” e起来编程暨武汉大学2020年大学生程序设计大赛决赛(重现赛))