A. Pupils Redistribution
题意:给2行数字,问最少第一行与第二行交换次数,使得第一行所有数字的出现次数等于第二行,如做不到相同输出-1。
thinking:直接2行的每个数字相加,判断其%2是否等于0,如果不等则输出-1。
然后把所有2行的次数差的绝对值相加,用总绝对值/4即可。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
using namespace std;
int q1[6];
int q2[6];
int main(){
//freopen("in.txt","r",stdin);
int i,j,k,f1,f2,f3,t1,t2,t3,n,m;
scanf("%d",&n);
memset(q1,0,sizeof(q1));
memset(q2,0,sizeof(q2));
int sum1=0;
int sum2=0;
for(i=1;i<=n;i++){
scanf("%d",&t1);
q1[t1]++;
}
for(i=1;i<=n;i++){
scanf("%d",&t2);
q2[t2]++;
}
if((q1[1]+q2[1])%2!=0||(q1[2]+q2[2])%2!=0||(q1[5]+q2[5])%2!=0||(q1[3]+q2[3])%2!=0||(q1[4]+q2[4])%2!=0){
cout << "-1" << endl;
}else{
sum1=abs(q1[1]-q2[1])+abs(q1[2]-q2[2])+abs(q1[3]-q2[3])+abs(q1[4]-q2[4])+abs(q1[5]-q2[5]);
cout << sum1/4 << endl;
}
return 0;
}
B. Weird Rounding
题意:给一串数字,和一个数字K,问这串数字最少去掉几个(digit)也就是位数,可以让其(divisible)整除by 10^k,注意0可以整除任何数,但是必须将这串数字删除到只剩下一个0,如果2个0的值是不能计算为一个0的,给的数字确保是能整除的。
thinking:判断这串数字的长度是否大于k,如果不大于直接输出(长度-1)也就是0,如果大于k,那么从这串数字的右边i=0开始,找0的个数等于k时的那个i的值,然后输出(i+1)-k,如果找不到0个数等于k,则直接输出(长度-1)。
the reason of failure:1、范围特例,没有考虑到N可以为0这个特殊情况。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
using namespace std;
int qq[15];
int main(){
//freopen("in.txt","r",stdin);
int i,j,k,f1,f2,f3,t1,t2,t3,n,m;
long long c1,c2,c3;
memset(qq,0,sizeof(qq));
cin >> c1 >> k;
c3=c1;
// c2=pow(10,k);
t1=1;
n=0;
while(c3){
qq[t1++]=c3%10;
c3=c3/10;
n++; //n位数
}
if(n>k){
f1=0;f2=0;
for(i=1;i<=n;i++){
if(qq[i]==0)f1++;
if(f1==k){ //0的数量够
f2=i-k;
cout << f2 <<endl;
return 0;
}
} //如果0的数量不够,那就只留下只有1个0
cout << n-1 <<endl;
return 0;
}else{ //如果位数小于 也是留下一个0
if(c1==0)
cout << 0 << endl;
else
cout << n-1 <<endl;
}
return 0;
}
C. Dishonest Sellers
题意:给2个数字N和K,分别表示要买N件商品和第一次购物至少要买K件商品,然后给2行每行均有N个数字,分别表示第N件在第一次购物与第二次购物的价格,
第二次购物的价格并不一定比第一次低,问买N件商品最小花费。
thinking :第一次全部购物的总价格为sum1,然后循环一遍第二次购物价格低于第一次的商品个数t1,并把第一次-第二次的价格差重新放到一个数组中,然后排序,判断是t1大还是N-K大,如果是t1大,那么应尽量买降价的商品,也就是用sum1-降价最多的N-K件商品,如果是N-K大,则第二次只把t1件降价的商品买了,也就是sum1-t1件降价商品的总降价金额。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
using namespace std;
int q1[200500];
int q2[200500];
int q3[200500];
int main(){
//freopen("in.txt","r",stdin);
int i,j,k,f1,f2,f3,t1,t2,t3,n,m;
long long c1,c2,c3;
memset(q1,0,sizeof(q1));
memset(q2,0,sizeof(q2));
memset(q3,0,sizeof(q3));
scanf("%d%d",&n,&k);
c1=0;
for(i=1;i<=n;i++){
scanf("%d",&q1[i]);
c1+=q1[i];
}
t1=0;
for(i=1;i<=n;i++){
scanf("%d",&q2[i]);
q3[i-1]=q1[i]-q2[i];
if(q1[i]>=q2[i])t1++;
}
sort(q3,q3+n);
//cout << c1 <<endl;
//cout << n-k << " " << t1 <<endl;
if(t1>=n-k){ //有t1个是降价的
for(i=1;i<=n-k;i++){ //买2个降价多的
c1-=q3[n-i];
}
cout << c1 <<endl;
}else{ //降价的较少,只买降价的
for(i=1;i<=t1;i++){
c1-=q3[n-i];
}
cout <<c1 << endl;
}
return 0;
}
D. String Game(逆向思维+二分)----二分不一定非得按照顺序才使用,查找都可以尝试用
题意:就是给2段字符串p,t,确保在顺序不变的情况刷,t可以由从p的一个个按顺序排字符组成,也就是ababcba里面有abb, 然后下一行一排数字,分别按照这些数字的顺序将这些数字一个个删除,问在保证t可以从p中找到的情况下,最多可以删除几个字符。
thinking:(看题解的)
做题的时候,题目一直看错,花了一个小时在瞎做,怪不得样例一直不过,后面剩的时间不多太慌了,
刚开始一直是想如何有更短复杂度的正向的查找方法,结果一直在O(N^2)的方法找不到更短了,然后想着正向找线性的方法,也没法,这种题应该换个打破常规用另外的方法去做的。
如例子
ababcba abb 5 3 4 1 7 6 2用qq[5]=1.qq[3]=2,qq[4]=3,qq[5]=4.表示第qq[n]为第n次删除,然后二分来找,l=0,r=strlen(p),while(r>l)mid=(l+r)/2+1,for由i开始也就是从第一个字符开始找,是从通过qq[i]的值大于mid(也就是第mid次删除)的提取出到一个新的数组里,这样是为了保证提取的字符顺序不乱,然后判断其是否能拼成t,如果不能,那么r=mid-1,如果能,那么l=mid,
这样可以找到r为最大值,也就是最多可以删除r个字符。
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
char q1[200500];
char q2[200500];
int qq[200500];
char q3[200500];
int q4[200500];
int main(){
int i,j,k,l,f1,f2,f3,t1,t2,t3;
//freopen("in.txt","r",stdin);
memset(q1,0,sizeof(q1));
memset(q2,0,sizeof(q2));
memset(qq,0,sizeof(qq));
memset(q3,0,sizeof(q3));
memset(q4,0,sizeof(q4));
scanf("%s",q1+1);
scanf("%s",q2+1);
int l1,l2;
l1=strlen(q1+1);
l2=strlen(q2+1);
for(i=1;i<=l1;i++){
scanf("%d",&qq[i]);
q4[qq[i]]=i;
}
int r;
l=0;r=l1;
int mid;
while(l<r){
mid=(l+r)/2+1;
t1=0;
for(i=1;i<=l1;i++)if(q4[i]>mid){ //��ΧӦ����
q3[++t1]=q1[i];
}
t2=1;
for(i=1;t2<=l2&&i<=t1;i++){
if(q3[i]==q2[t2])t2++;
}
if(t2>l2)l=mid;
else r=mid-1;
}
cout << l << endl;
return 0;
}