C语言完美的代价视频,完美的代价C语言

http://www.itjxue.com  2023-01-20 22:35  来源:未知  点击次数: 

求大神帮我解释下这个c语言题目“完美的代价”

#includestdio.h ?

int changes(char s[],char x,int n); //声明一个int返回值的函数,传递的变量为字符串s,字符x和整型数n

char x='0'; //声明字符x为'0'

int main(void) //主函数,程序的入口

{

? int n,i,k=0,b[26]={0},j; //声明变量,b[26]={0}是让b这个数组的26个值全为0,为了记录26个字母分别出现多少次

? char y,s[8000]={0}; //s[8000]是用数组定义字符串

? scanf("%d",n); //输入字符串的长度

? getchar(); //吸收缓冲区内的回车,或者后面输入%c前加一个空格效果一样

? for(i=0;in;i++) //输入长度为n字符串,以数组格式储存

? ????scanf("%c",s[i]);

? for(i=0;in;i++)

? {

? ? ? j=s[i]-'a'; //将字母转化为字母的序数,用到了字母的ASCII值,注意j定义的类型是int

? ? ? b[j]++; //次数加1

? }

? for(j=0;j26;j++)

? {

? ? ? if(b[j]%2!=0)

? ? ? {

? ? ? ? ? k++; //记录出现奇数次的字母的个数

? ? ? ? ? x=j+'a';//j+'a'是用ASCII值将字母还原,这里x记录的是奇数次字母,可以知道若是k=1则x代表的字母一定在中间

? ? ? ? ?

? ? ?}

? }

? if(k=2)

? ????printf("Impossible\n"); //易知出现奇数次的字母的个数大于1则无法变成回文的字符串

else

? ????printf("%d\n",changes(s,x,n)); //changes函数可以计算至少交换多少次

? return 0;

} ?

int changes(char s[],char x,int n) //定义函数,传递变量

{

? ?int i,change=0,j,k; //如字面,change代表交换次数

? ?for(i=0;in/2;i++)//对一半的字符进行循环,不包括中间的字符(如果有的话)

? ?{

? ? ? if(s[i]==x)

? ? ? {

? ? ? ? for(j=i;jn-i-1;j++) //从s[i]开始判断,一直到与之对称的那个字符,如s[0]与s[n-1]对称

? ? ? ? ????if(s[n-i-1]==s[j]) //若中间有一个与对称的字符相等的字符,则将其放到s[i]的前面,共交换了j-i次,所以后面change加了j-i

? ? ? ? ????????break;

? ? ? ? change+=j-i;

? ? ? ? for(k=j;ki;k--) //交换过程

? ? ? ? ????s[k]=s[k-1]; //j-1--j;j-2--j-1;...i--i+1

? ? ? ? s[i]=s[n-i-1]; //由于s[n-i-1]=s[j],所以是j--i

? ? }

? ? ? else

? ? ? {

? ? ? for(j=n-i-1;j=i;j--) //同上,只不过是从对称的往回找

? ? ? ????if(s[i]==s[j])

? ? ? ????????break;

? ? ? change+=n-i-1-j;

? ? ? for(k=j;kn-i-1;k++) //将s[j]放到s[n-i-1]的后面

? ? ? ????s[k]=s[k+1]; //交换过程

? ? ? s[n-i-1]=s[i];

? ? ? }

? ?} ?

? ?return change; //返回交换次数

}

/*具体每句语句的意思和作用就这样了

不清楚的地方可以继续问

至于为什么这样次数是最少的

还是自己举几个例子看看吧*/

谁有关于c语言的视频教程,初学到高级的,最好是百度网盘资料,谢谢!

《C语言视频教程》百度网盘高清资源免费在线观看

链接:?

作品相关介绍:

C语言是一门面向过程的、抽象化的通用程序设计语言,广泛应用于底层开发。C语言能以简易的方式编译、处理低级存储器。

解出并解释一下C语言的这个题目(完美的代价)

//说明:此程序编译通过的,你看看吧。最短交换的算法就是:交换从两端到中间,就是最优。

//算法思想具体如下:

1、从左边第i的字符串开始逐个开始与x比较是否相等

2、在字符串右边第n-i-1个位置开始,向左寻找与之相同的字符。

3、找到字符后将其逐个向右移动,统计交换次数

当遇到奇数字母时,反向搜索。见代码。即看2’的算法

2‘、在字符串左边第i个位置开始,向右寻找与第n-i-1位置相同的字符。

#includestdio.h

int changes(char s[],char x,int n);

char x='0';

void main()

{

int n,i,k=0,b[26]={0},j;

char y,s[8001]={0};

scanf("%d",n);

getchar();

for(i=0;in;i++)

scanf("%c",s[i]);

for(i=0;in;i++){//数组 j=s[i]-'a';将字符转换成ACS码,b[]统计各个字母的个数

j=s[i]-'a';

b[j]++;

}

for(j=0;j26;j++){/*如果所有字母出现偶数次,那么该字符串可以进行字符间的交替,成为回文串。即(b[j]%2!=0);*/

if(b[j]%2!=0){//统计共有几个奇数字母

k++;

x=j+'a';//x是奇数字母(一个奇数字母的时候有用)

}

}

if(k=2)/*如果有两个字母或者两个字母以上出现了奇数次,那么该字符串不能通过字符间的交替成为回文串。*/

printf("Impossible\n");

else

printf("%d\n",changes(s,x,n));

}

int changes(char s[],char x,int n)//统计交换次数

{

int i,change=0,j,k;

for(i=0;in/2;i++){

if(s[i]==x){//当遍历到奇数字母时,可以以回文对应位置的字母来交换

for(j=i;jn-i-1;j++)

if(s[n-i-1]==s[j])

break;

change+=j-i;

for(k=j;ki;k--)

s[k]=s[k-1];

s[i]=s[n-i-1];

}

else//否则,以左边字母进行交换次数统计

{

for(j=n-i-1;j=i;j--)

if(s[i]==s[j])

break;

change+=n-i-1-j;

for(k=j;kn-i-1;k++)

s[k]=s[k+1];

s[n-i-1]=s[i];

}

}

return change;

}

解释一下C语言的这个题目(完美的代价)

简单说下

n是字符串下标,

n1里面没看到用,

x是相同字符的计数器x为奇数时,则回文串有中间的单一字符,x为偶数时,则无中间单字符;

y为记录单一字符的,若输入串中有2个单一字符(y==2成立),则输入串不能成为回文串;

m为记录交换次数;i是操作用的下标;

j是i+1以后的字符下标(初始值是i的对称);

k为b[27]的下标记录串中的回文字符数;

tong为了避免重复操作;

*a为输入的串;

b[27]记录已经排好的字符;

ch为交换时的临时变量;

dan为 记录单一字符(如试例中的d)

大for中的第一个for是判断输入串是否能成回文串,是否有中间单一字符,有则找出;

之后 有中间字符dan,使它向n/2移动;最后的2个for是 使输入串前后回文。

小弟不才 仅于此

(责任编辑:IT教学网)

更多

推荐鼠标代码文章