if(a>b&&a>c){
if(b>c)printf("ABC");
elseprintf("ACB");
}
if(b>a&&b>c){
if(a>c)printf("BAC");
elseprintf("BCA");
}
if(c>a&&c>b){
if(a>b)printf("CAB");
elseprintf("CBA");
}
}
}
}
}
getchar();
return0;
}
7、求排列的逆序数
描述
在Internet上的搜索引擎经常需要对信息进行比较,比如可以通过某个人对一些事物的排名来估计他(或她)对各种不同信息的兴趣,从而实现个性化的服务。
对于不同的排名结果可以用逆序来评价它们之间的差异。
考虑1,2,…,n的排列i1,i2,…,in,如果其中存在j,k,满足jik,那么就称(ij,ik)是这个排列的一个逆序。
一个排列含有逆序的个数称为这个排列的逆序数。
例如排列263451含有8个逆序(2,1),(6,3),(6,4),(6,5),(6,1),(3,1),(4,1),(5,1),因此该排列的逆序数就是8。
显然,由1,2,…,n构成的所有n!
个排列中,最小的逆序数是0,对应的排列就是1,2,…,n;最大的逆序数是n(n-1)/2,对应的排列就是n,(n-1),…,2,1。
逆序数越大的排列与原始排列的差异度就越大。
现给定1,2,…,n的一个排列,求它的逆序数。
输入
第一行是一个整数n,表示该排列有n个数(n<=100000)。
第二行是n个不同的正整数,之间以空格隔开,表示该排列。
输出
输出该排列的逆序数。
样例输入
6
263451
样例输出
8
提示
1.利用二分归并排序算法(分治);
2.注意结果可能超过int的范围,需要用longlong存储。
#include
usingnamespacestd;
constintMAX_NUM=100000+5;
longlongseq[MAX_NUM];
intN;
longlongans;
voidreSeq(longlong*seq,intlef,intrigh){,&num[i].y);
}
intans;
sort(num,num+t,cmp);
if(t%2==1)
{
ans=0;
intzong=num[t/2].y;
for(i=0;i{
ans+=abs(num[i].y-zong);
}
}
else
{
intzong=num[t/2].y+num[t/2-1].y;
zong/=2;
ans=0;
for(i=0;i{
ans+=abs(num[i].y-zong);
}
}
printf("%d\n",ans);
return0;
}
12、0/1背包问题
描述
给定n种物品和一个背包,物品i(1≤i≤n)的重量是wi,其价值为vi,背包的容量为C,对每种物品只有两种选择:
装入背包或者不装入背包。
如何选择装入背包的物品,使得装入背包中物品的总价值最大
输入
输入包含一组或多组测试例。
每组测试例的第一行是物品的数量n和背包的容量C,之后的n行是每个物品的重量及其价值。
输出
输出第一行是装入背包中物品的总价值,后面n行是各个物品装入背包的情况。
样例输入
510
26
23
65
54
46
样例输出
15
1
1
0
0
1
源代码:
#include<>
#include
usingnamespacestd;
intdp[110][1010];
intn,c,ans[110];
intw[110],v[110];
voidprint(){
inti,j,k;
k=c;
for(i=n;i>=1;i--){
if(dp[i][k]!
=dp[i-1][k]){
ans[i]=1;
k=k-w[i];
}
else{
}
}
return;
}
intmain(){
inti,j,k;
scanf("%d%d",&n,&c);
for(i=1;i<=n;i++){
scanf("%d%d",&w[i],&v[i]);
}
for(i=1;i<=n;i++){
for(j=1;j<=c;j++){
dp[i][j]=dp[i-1][j];
if(j>=w[i]){
dp[i][j]=max(dp[i-1][j-w[i]]+v[i],dp[i][j]);
}
}
}
printf("%d\n",dp[n][c]);
print();
for(i=1;i<=n;i++){
printf("%d\n",ans[i]);
}
return0;
}
13、最少硬币问题
描述
设有n种不同面值的硬币,各硬币的面值存于数组T[1:
n]中。
现要用这些面值的硬币来找钱。
可以使用的各种面值的硬币个数存于数组Coins[1:
n]中。
对任意钱数0≤m≤20001,设计一个用最少硬币找钱m的方法。
对于给定的1≤n≤10,硬币面值数组T和可以使用的各种面值的硬币个数数组Coins,以及钱数m,0≤m≤20001,计算找钱m的最少硬币数。
输入
由文件提供输入数据,文件的第一行中只有1个整数给出n的值,第2行起每行2个数,分别是T[j]和Coins[j]。
最后1行是要找的钱数m。
输出
将计算出的最少硬币数输出到文件中。
问题无解时输出-1。
样例输入
3
13
23
53
18
样例输出
5
提示
运用动态规划法进行算法设计并编程实现。
源代码:
#include<>
#include
usingnamespacestd;
intw[110],v[110];
intdp[110][20010];
intn,m;
voidinit(){
for(inti=0;i<110;i++){
for(intj=0;j<20010;j++){
}
}
}
intmain(){
inti,j,k;
intt,x,cnt=1;
scanf("%d",&n);
for(i=1;i<=n;i++){
scanf("%d%d",&t,&x);
for(j=1;j<=x;j++){
w[cnt]=t;
v[cnt]=1;
cnt++;
}
}
scanf("%d",&m);
init();
for(i=0;i.,An},考察这n个矩阵的连乘积A1A2...An。
由于矩阵乘法满足结合律,故计算矩阵的连乘积可以有许多不同的计算次序,这种计算次序可以用加括号的方式来确定。
矩阵连乘积的计算次序与其计算量有密切关系。
例如,考察计算3个矩阵{A1,A2,A3}连乘积的例子。
设这3个矩阵的维数分别为10*100,100*5,和5*50。
若按(A1A2)A3计算,3个矩阵连乘积需要的数乘次数为10*100*5+10*5*50=7500。
若按A1(A2A3)计算,则总共需要100*5*50+10*100*50=75000次数乘。
现在你的任务是对于一个确定的矩阵连乘方案,计算其需要的数乘次数。
输入
输入数据由多组数据组成。
每组数据格式如下:
第一行是一个整数n(1≤n≤26),表示矩阵的个数。
接下来n行,每行有一个大写字母,表示矩阵的名字,后面有两个整数a,b,分别表示该矩阵的行数和列数,其中1第n+1行是一个矩阵连乘的表达式,由括号与大写字母组成,没有乘号与多余的空格。
如果表达式中没有括号则按照从左到右的顺序计算,输入的括号保证能够配对。
输出
对于每组数据,输出仅一行包含一个整数,即将该矩阵连乘方案需要的数乘次数。
如果运算过程中出现不满足矩阵乘法法则的情况(即左矩阵列数与右矩阵的行数不同),则输出“error”。
样例输入
3
A10100
B1005
C550
A(BC)
样例输出
75000
源代码:
#include<>
#include
#include
#include<>
#include<>
#include
usingnamespacestd;
intn,ans;
stringexp,str;
intx,y;
structnode{
intx,y;
};
nodes[200];
intflage;
stackope;
stackv;
stringchange(stringt){
intlength=();
stringdes="";
for(inti=0;iif(isalpha(t[i])){
if(t[i+1]==')'){
des=des+t[i];
}
else{
des=des+t[i]+'*';
}
}
elseif(t[i]=='('){
des=des+t[i];
}
else{
if(t[i+1]==')'){
des=des+t[i];
}
else{
des=des+t[i]+'*';
}
}
}
des=des+t[length-1]+'=';
returndes;
}
nodecalc(nodea,nodeb){
if!
={
flage=1;
}
nodet;
ans=ans+**;
=;=;
returnt;
}
charcompare(chari,charj){
if(i=='='){
if(j!
='='){
return'<';
}
else{
return'=';
}
}
if(i=='('){
if(j==')'){
return'=';
}
else{
return'<';
}
}
if(i=='*'){
if(j=='('){
return'<';
}
else{
return'>';
}
}
}
intmain(){
inti,j,k;
stringe;
while(cin>>n){
for(i=1;i<=n;i++){
cin>>str>>x>>y;
s[str[0]].x=x;
s[str[0]].y=y;
}
cin>>e;
flage=0;
ans=0;
exp=change(e);
while(!
()){
();
}
while(!
()){
();
}
('=');
intl=();
for(k=0;k<=l-1;){
if(isalpha(exp[k])){
(s[exp[k]]);
k++;
}
else{
if(compare(),exp[k])=='='){
();
k++;
}
elseif(compare(),exp[k])=='<'){
(exp[k]);
k++;
}
else{
nodea=();
();
nodeb=();
();
(calc(b,a));
();
}
}
}
if(!
flage)
cout<else
cout<<"error"<}
return0;
}
15、多边形游戏
描述
一个多边形,开始有n个顶点。
每个顶点被赋予一个正整数值,每条边被赋予一个运算符“+”或“*”。
所有边依次用整数从1到n编号。
现在来玩一个游戏,该游戏共有n步:
第1步,选择一条边,将其删除
随后n-1步,每一步都按以下方式操作:
(1)选择一条边E以及由E连接着的2个顶点v1和v2;
(2)用一个新的顶点取代边E以及由E连接着的2个顶点v1和v2,将顶点v1和v2的整数值通过边E上的运算得到的结果值赋给新顶点。
最后,所有边都被删除,只剩一个顶点,游戏结束。
游戏得分就是所剩顶点上的整数值。
那么这个整数值最大为多少
输入
第一行为多边形的顶点数n(n≤20),其后有n行,每行为一个整数和一个字符,整数为顶点上的正整数值,字符为该顶点到下一个顶点间连边上的运算符“+”或“*”(最后一个字符为最后一个顶点到第一个顶点间连边上