C语言完美的代价视频,完美的代价C语言
求大神帮我解释下这个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是 使输入串前后回文。
小弟不才 仅于此