比赛:西安电子科技大学第16届程序设计竞赛网络同步赛
队伍出题:7/10
个人出题:2
今天我个人的表现算是比较差了。。。
简单说一下。。。
A:给你数字0-10的英文单词让你你输出拼音。。。直接建立一个map即可。。。居然还交了一发ce。。。
B:给你一些字母和一个字典,求能用这些字母组成字典中最长单词的长度。直接计数一下然后比较每个单词的每种字母数是否小于等于给定对应字母的数量即可。
C:n个数随机挑两个,定义其组合值为小的那个数的值,求这些组合中第K大的值是多少。这个枚举一下不难发现n个数从大到小排,组合值为数a[i]的有i个,然后枚举一下再k减去i就可以了。。。
D:给n个数,每次拿出来两个,再把拿出来的两个数的和/2放回去,求数组里最后剩下的那个数的期望值的整数部分。
猜的吧。。。队友猜的sum[n]/n就对了。。。虽然我不会证明但我也觉得这样肯定对。。。
E:这道题可以说是决定我们排名的关键性一题了,用的DP。给你01串,随机挑选其中一些子串组成的数的十进制能整除3的所有方法总数,有前导0。dp[i][j]表示到01串第i个位置,%3=j的方法总数。(j=0,1,2) 用DP还是容易想到的,但是状态转移以及初始化可就要考验能力了。可以说是DP的好题。
代码:
#include <bits/stdc++.h>
using namespace std;
long long dp[1000005][3];
string b;
int main()
{
int n;
long long sum;
while(cin>>b)
{
sum=0;
memset(dp,0,sizeof(dp));
n=b.length();
if(b[0]=='0')dp[0][0]=1;
else dp[0][1]=1;
for(int i=1;i<n;i++)
{
if(b[i]=='0')
{
dp[i][0]=dp[i-1][0]+1;
dp[i][1]=dp[i-1][2];
dp[i][2]=dp[i-1][1];
}
else
{
dp[i][0]=dp[i-1][1];
dp[i][1]=dp[i-1][0]+1;
dp[i][2]=dp[i-1][2];
}
}
for(int i=0;i<n;i++)
{
sum+=dp[i][0];
}
cout<<sum<<endl;
}
}
F:你要把m个数填到n个格子里,如果格子满了并且格子里没有要填的数就要取出一个来,把这个数放进去。每往格子里放一次都需要一步,求最少需要多少步。
这道题我见到了三个思路,都是AC:
一、直接把m个数去重,剩下的数数量输出。。。
二、用优先队列维护第i个数以后所有数出现的最小数量,每次替换最小的。比赛的时候AC了也没注意,其实很容易举出反例证明这样是错的。。。数据水。。。
三、每次要填数时,找n个格子中已经填入的、在m个数中出现的位置最靠后的那个数来替换。也想过这个思路,但是每次找我怕TLE,结果AC了。
G:你有x和y各1个,每次可以执行两种操作:1、变为x+y,y 2、变为2*x,x,求要使x变为n最少需要执行多少次操作。
我毫无思路,用bfs打了前100项的结果给了队友,于是队友成功找出规律然后AC。。。也是佩服
剩下的题待补。。。
今天个人发挥不太满意。。。明天要加油。。。不能拖后腿。。。