组个最小数
题目大意:给定0~9十个数字各自的数目,要求所有的给定数字必须全部用上,并使组成的数字最小
难度:容易
输入样例:2 2 0 0 0 3 0 0 1 0
输出样例:10015558
#include <iostream>
using namespace std;
//先从非零的数中选一个最小的当做首位,然后后面就可以从所有的数中从小到大的选
int main()
{
int N=10,a[10]={0},i=0;
while(N--)
{
cin>>a[i];
i++;
}
for(int i=1;i<=9;i++)
{
if(a[i]>0)
{
cout<<i;
a[i]--;
break;
}
}
for(int i=0;i<10;i++)
{
if(a[i]>0)//这个判断可以省去
{
for(int j=0;j<a[i];j++)
{
cout<<i;
}
}
}
cout<<"ok"<<endl;
}
从商店里坑最多的钱
题目大意:给定多个coupon,多个商品,都为整数(正、负、零),我们最终得到的钱是coupon与商品的乘积和,求最大
难度:较易
输入样例:
4
1 2 4 -1
4
7 6 -2 -3
输出样例:
43
#include <iostream>
#include <algorithm>
using namespace std;
//先利用sort函数从小到大排序,然后从头处理负数,接着从尾部开始倒着处理正数
const int maxnum=100010;
int main()
{
int coupon[maxnum],good[maxnum],ans=0,k=0,z=0;
int m,n;
cin>>m;
int m1=m;//注意记录,不然会为零
for(int i=0;m>0;m--,i++)
{
cin>>coupon[i];
}
cin>>n;
int n1=n;//注意记录
for(int i=0;n>0;n--,i++)
{
cin>>good[i];
}
sort(coupon,coupon+m1);
sort(good,good+n1);
while(coupon[k]<0&&good[z]<0&&k<m1&&z<n1)
{
ans+=coupon[k]*good[z];
k++;
z++;
}
k=m1-1;
z=n1-1;
while(coupon[k]>0&&good[z]>0&&k>=0&&z>=0)
{
ans+=coupon[k]*good[z];
k--;
z--;
}
cout<<ans<<endl;
cout<<"ok"<<endl;
}
swap最小的次数复原序列
题目大意:给定一个序列(有n个数,n<100000),从0到n-1,但是顺序打乱,请用最少的swap次数将这个序列复原,但是限制是每次的swap中的参数都要含有0这个元素
难度:中等
测试案例:
5 0 1 2 3 4
output
0
5 1 2 3 4 0
output
4
9 0 2 1 4 3 6 5 8 7
output
12
思路:输入的时候获取0的位置,比如是num[5],那么就把0与5交换(5归位),直到0归位,如果此时还是乱序,那么将0与最近的一个没有归位的元素调换,然后重复上一步。最后0归位的时候应该就是顺序。
#include <iostream>
#include <algorithm>
using namespace std;
const int maxnum=100010;
int main()
{
int m,num[maxnum],i=0,zero,count=0,miss=0;//zero记录的是0的位置,随时更新,count记录的是调换的次数,miss记录的是没有归位的元素的个数
cin>>m;
int m1=m;//注意记录
while(m--)
{
cin>>num[i];
if(num[i]==0)
{
zero=i;
}
if(num[i]!=i)
{
miss++;
}
i++;
}
while(true)
{
if(num[0]==0)
{
if(miss==0) break;//退出总循环
for(int i=0;i<m1;i++)
{
if(num[i]!=i)
{
swap(num[0],num[i]);
zero=i;
count++;
miss++;
break;//在这层循环中一旦找到就马上退出
}
}
}
else
{
for(int i=0;i<m1;i++)
{
if(num[i]==zero)
{
swap(num[i],num[zero]);
count++;
if(i==0)
{
miss-=2;
}
else
{
miss--;
}
zero=i;
break;//在这层循环中一旦找到就马上交换退出
}
}
}
}
cout<<count<<endl;
cout<<"ok"<<endl;
}
拼接产生最小的字符串
题目大意:给出n个字符串片段(都是数字),然后要求把它们拼接起来,求最小的情况,开头如果是0的话就要去掉
难度:容易
测试案例
输入
5
32 321 3214 0229 87
输出
22932132143287
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
const int maxnum=10010;
bool cmp(string a,string b)
{
return a+b<b+a;//如果a+b<b+a,那么就把a排在b的前面
}
//此题的关键是要进行拼接尝试,不能说a<b就把a排在b的前面了,所以比较函数需要另外设计
int main()
{
int m;
string str[maxnum],ans="";
cin>>m;
for(int i=0;i<m;i++)
{
cin>>str[i];
}
sort(str,str+m,cmp);
for(int i=0;i<m;i++)
{
ans+=str[i];
}
while(ans.size()&&ans[0]=='0')//注意这里是字符
{
ans.erase(ans.begin());//这里参照stl博客,有多种写法
}
if(ans.size()==0) cout<<0<<endl;
else
{
cout<<ans<<endl;
}
cout<<endl;
cout<<"ok"<<endl;
}