1、题目:小明预进行一场闯关小游戏,一共有n关,每关游戏有a[i]个按钮,其中只有1个是正确按钮且的正确按钮位置是不变(可以记忆,)
按到正确按钮继续闯关,按到错误按钮重新返回第一关开始
求:小明闯关成功最多需要按按钮的次数。
例:输入[2,2,2]输出9
public long findMaxButtons(int[] a){
long res=a.length;//
for(int i=0;i<a.length;i++){
//第i关要失败a[i]-1次,每次都要按i次按钮
res+=(long)(a[i]-1)(i+1);
}
return long;
}
2、刷墙
最近小明搬到了新家,正在粉刷墙壁,不幸的是他粉刷的墙壁并不理想,它的墙壁是一个长度为n的格子,
每个格子用0表示红色,用1表示蓝色,现在墙壁是一个非常混乱的颜色,他想将墙壁左边涂成全是蓝色
右边全是红色,可以将墙壁刷成全是红色或蓝色,请问他至少需要粉刷多少个格子墙壁成为他需要的样子。
输入描述:
第一行一个整数n(1<=n<=100000)
第二行长度为n的01串,0表示红色,1表示蓝色
输出:
一个整数表示最少粉刷次数。
解析:一个长度为n的字符01组成的字符串,要把串变成某个位置及其左边全是1,右边全是0至少修改多少个字符。
1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 |
1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 |
把[1,i]这个区间内的数全变为1的次数等于这个区间0的个数
把[i+1,n]这个区间内的数全变为0的次数等于这个区间1的个数
可以预处理前缀和sum[i]为[1,i]中1的个数
然后可以在o(1)时间复杂度内求出每个分界点要变化的数的个数,更新答案即可。
前缀和:
在经过一次O(n)的预处理后,可以O(1)查询区间和
sum[i]=sum[i-1]+a[i]
和: sum 1 3 6 10 15
数据:a 1 2 3 4 5 6 7 8
下标: 0 1 2 3 4 5 6 7 8
sum[i]表示下标为[1,n]的权值和
[l,r] sum[r]-sum[l-1]
char s[N];
int sum[N];
int main()
{
int n;
scanf("%d%%s",&n,s+1);
for(int i=1;i<=n;i++)
sum[i]=sum[i-1]+s[i]-'0';
int res=n;
for(int i=0;i<=n;i++){
//[1,i]中'0'的个数为i-sum[i]
//[i+1,n]中'1'的个数为sum[n]-sum[i]
res=min(res,i-sum[i]+sum[n]-sum[i]);
}
printf("%d\n",res);
return 0;
}
3、 胜者为王
小赵、小钱、小孙三人正在进行一个游戏,游戏中有n个回合,每个人都有一个字符串,三人的字符串长度相等,
每个回合它们必须要改字符串中的一个字母,最后每个人的分数是自己字符串中出现字符最多的字母的分数,
分数最高者获胜,输出获胜者的名字,若有两人或以上相同分数输出draw
输入:
7
treasurehunt
threefriends
hicodeforces
输出:
xiao wang
一行一个字符串,表示游戏结束。
解析:
对于每个人来说有一个显而易见的贪心策略,就是先找出出现次数最多的字母是哪个,然后把其他字母
尽可能都改成这个字母
设出现次数最多的字母数量是x,在进行n回合,这个字母可以是min(x+n,len)个;
char a[N],b[N],c[N];
int cnt[256];
int main()
{
int n;
scanf("%d%s%s%s",&n,a,b,c);
int x=0,y=0,z=0;
for(int i=0;a[i];i++)x=max(x,++cnt(a[i]));
memset(cnt,0,sizeof(cnt));
for(int i=0;b[i];i++)x=max(x,++cnt(b[i]));
memset(cnt,0,sizeof(cnt));
for(int i=0;c[i];i++)x=max(x,++cnt(c[i]));
//memset(cnt,0,sizeof(cnt));
int len=strlen(a);
x=min(x+n,len);
y=min(y+n,len);
z=min(z+n,len);
if(x>yandx>z) puts("xiaoming");
else if(y>xandy>z) puts("xiaowang");
else if(z>x and z>y) puts("xiaoli");
else puts("draw");
return 0;
}