“手环转珠”问题求解

C++语言 码拜 9年前 (2015-05-11) 1247次浏览 0个评论

题目描述
有一条彩色的手环,上面拥有10种不同颜色的珠子颜色,其中假设蓝色为B、黑色为K、白色为W、黄色为Y、红色为R、粉红色为P、水蓝色为C、绿色为G、橙色为O、银色为S。

已知珠子能在手环上旋转(不考虑翻面),例如BKYRPW可转成PWBKYR,今给定2组珠子颜色顺序,求由前组颜色顺序转成后组颜色顺序最少要转动几次。

Ps代码量越短越好

本人小白,跪求给位大大指点,给分40

5分
纯暴力做法

#include <algorithm>
#include <deque>
#include <iostream>
#include <string>

using namespace std;

int main()
{
	string str1, str2;
	cin >> str1 >> str2;
	if (str1.size() != str2.size())
	{
		cerr << "size not match!" << endl;
		return 1;
	}
	deque<char> s1(str1.begin(), str1.end());
	size_t count = 0;
	while (!equal(s1.begin(), s1.end(), str2.begin()))
	{
		s1.push_back(s1.front());
		s1.pop_front();
		count++;
	}
	if (count == str1.size())
	{
		cerr << "string not match!" << endl;
		return 1;
	}
	count = min(count, s1.size() - count);
	cout << count << endl;
	return 0;
}
5分
哎,我知道我的代码纯粹是唬人的废物,但看在我这么辛苦的份上,楼主好歹给个关照分吧,谢谢。。。

#include <stdio.h>
#include <windows.h>
void main()
{
    char shou[10],chuan[10],c;
	int a,start=0,end=0;
    printf("请输入开始状态的手串:");
	for(a=0;a<10;a++)scanf("%c",&shou[a]);// 最多输入十个字符,然后按下回车,切记!
	scanf("%c",&c); // 这个BUG我找了很长时间!之所以加上这句话,是为了喝掉那个回车输入!
	printf("\n请输入结束状态的手串:");
	for(a=0;a<10;a++)scanf("%c",&chuan[a]);

	for(a=0;a<9;a++)
	{
		start = start + (shou[a] - shou[a+1])*(shou[a] - shou[a+1]);// 之所以相乘两次,是因为我无法解决俩数相减变成负数的问题,惭愧。。。
		end = end + (chuan[a] - chuan[a+1]) * (chuan[a] - chuan[a+1]);// 同上。。。
	}
	start = start + (shou[9] - shou[0]) * (shou[9] - shou[0]); end = end + (chuan[9] - chuan[0])*(chuan[9] - chuan[0]);
	if(start != end )
	{
		printf("\n两个状态的手串无法转换,请检查是否有误!");
		goto game_over;
	}
	for(a=0;shou[a]!=chuan[0]&&a<10;a++) ;
	printf("\n经过计算,最少需要%d次转换才能达到目的!",a);
game_over:
	system("pause");

}
5分
int match(const char *src,const char *dst){
    int l=strlen(src),ans,i;
    for(ans=0;ans<l;++ans){
        for(i=0;i<l;i++) if(src[(ans+i)%l]!=dst[i]) break;
        if(i==l) break;
    }
    return min(ans,l-ans);
}
5分
引用 2 楼 wenpinglaoyao 的回复:

哎,我知道我的代码纯粹是唬人的废物,但看在我这么辛苦的份上,楼主好歹给个关照分吧,谢谢。。。

#include <stdio.h>
#include <windows.h>
void main()
{
    char shou[10],chuan[10],c;
	int a,start=0,end=0;
    printf("请输入开始状态的手串:");
	for(a=0;a<10;a++)scanf("%c",&shou[a]);// 最多输入十个字符,然后按下回车,切记!
	scanf("%c",&c); // 这个BUG我找了很长时间!之所以加上这句话,是为了喝掉那个回车输入!
	printf("\n请输入结束状态的手串:");
	for(a=0;a<10;a++)scanf("%c",&chuan[a]);

	for(a=0;a<9;a++)
	{
		start = start + (shou[a] - shou[a+1])*(shou[a] - shou[a+1]);// 之所以相乘两次,是因为我无法解决俩数相减变成负数的问题,惭愧。。。
		end = end + (chuan[a] - chuan[a+1]) * (chuan[a] - chuan[a+1]);// 同上。。。
	}
	start = start + (shou[9] - shou[0]) * (shou[9] - shou[0]); end = end + (chuan[9] - chuan[0])*(chuan[9] - chuan[0]);
	if(start != end )
	{
		printf("\n两个状态的手串无法转换,请检查是否有误!");
		goto game_over;
	}
	for(a=0;shou[a]!=chuan[0]&&a<10;a++) ;
	printf("\n经过计算,最少需要%d次转换才能达到目的!",a);
game_over:
	system("pause");

}

我虽然没实际写过这种代码也没思考过该如何实现,不过你代码提到的那个你没解决的bug我告诉你怎么回事
scanf  是IO函数,基本格式化输入函数,但是这个函数,不会将回车取出来,他把回车放回到缓存区了,所以下次读取会直接吧回车读出来
修改代码

#include <stdio.h>
#include <windows.h>
void main()
{
    char shou[10],chuan[10],c;
	int a,start=0,end=0;
    printf("请输入开始状态的手串:");
	for(a=0;a<10;a++)scanf("%c",&shou[a]);// 最多输入十个字符,然后按下回车,切记!
        //刷输入缓存
	char ch;
       while((scanf("%c",&ch)!=EOF)&&(ch!=""\n""));
	printf("\n请输入结束状态的手串:");
	for(a=0;a<10;a++)scanf("%c",&chuan[a]);

	for(a=0;a<9;a++)
	{
		start = start + (shou[a] - shou[a+1])*(shou[a] - shou[a+1]);// 之所以相乘两次,是因为我无法解决俩数相减变成负数的问题,惭愧。。。
		end = end + (chuan[a] - chuan[a+1]) * (chuan[a] - chuan[a+1]);// 同上。。。
	}
	start = start + (shou[9] - shou[0]) * (shou[9] - shou[0]); end = end + (chuan[9] - chuan[0])*(chuan[9] - chuan[0]);
	if(start != end )
	{
		printf("\n两个状态的手串无法转换,请检查是否有误!");
		goto game_over;
	}
	for(a=0;shou[a]!=chuan[0]&&a<10;a++) ;
	printf("\n经过计算,最少需要%d次转换才能达到目的!",a);
game_over:
	system("pause");

}

还有,这种代码还有 个bug 就是输入10个字符的时候,如果我每输入一个就按一个回车,就可能触发我说的那个问题,下次输入会跳过,直接吧回车读了出来,请注意对用户边界输入情况的处理

5分
引用 2 楼 wenpinglaoyao 的回复:

哎,我知道我的代码纯粹是唬人的废物,但看在我这么辛苦的份上,楼主好歹给个关照分吧,谢谢。。。

#include <stdio.h>
#include <windows.h>
void main()
{
    char shou[10],chuan[10],c;
	int a,start=0,end=0;
    printf("请输入开始状态的手串:");
	for(a=0;a<10;a++)scanf("%c",&shou[a]);// 最多输入十个字符,然后按下回车,切记!
	scanf("%c",&c); // 这个BUG我找了很长时间!之所以加上这句话,是为了喝掉那个回车输入!
	printf("\n请输入结束状态的手串:");
	for(a=0;a<10;a++)scanf("%c",&chuan[a]);

	for(a=0;a<9;a++)
	{
		start = start + (shou[a] - shou[a+1])*(shou[a] - shou[a+1]);// 之所以相乘两次,是因为我无法解决俩数相减变成负数的问题,惭愧。。。
		end = end + (chuan[a] - chuan[a+1]) * (chuan[a] - chuan[a+1]);// 同上。。。
	}
	start = start + (shou[9] - shou[0]) * (shou[9] - shou[0]); end = end + (chuan[9] - chuan[0])*(chuan[9] - chuan[0]);
	if(start != end )
	{
		printf("\n两个状态的手串无法转换,请检查是否有误!");
		goto game_over;
	}
	for(a=0;shou[a]!=chuan[0]&&a<10;a++) ;
	printf("\n经过计算,最少需要%d次转换才能达到目的!",a);
game_over:
	system("pause");

}

至于2数相减变成负数,请检查你相减的2个数的大小情况,数学上有这么一种比较方法
C=A-B
如果C 是大于0 则A>B
如果C 小于0 则A<B
所以根据你的注释说明情况,估计你相减的左边的数比右边的数小
至于消除负数的方法,可以进行代码处理变成正数,而不是相乘

5分
引用 4 楼 jack960330 的回复:
Quote: 引用 2 楼 wenpinglaoyao 的回复:

哎,我知道我的代码纯粹是唬人的废物,但看在我这么辛苦的份上,楼主好歹给个关照分吧,谢谢。。。

#include <stdio.h>
#include <windows.h>
void main()
{
    char shou[10],chuan[10],c;
	int a,start=0,end=0;
    printf("请输入开始状态的手串:");
	for(a=0;a<10;a++)scanf("%c",&shou[a]);// 最多输入十个字符,然后按下回车,切记!
	scanf("%c",&c); // 这个BUG我找了很长时间!之所以加上这句话,是为了喝掉那个回车输入!
	printf("\n请输入结束状态的手串:");
	for(a=0;a<10;a++)scanf("%c",&chuan[a]);

	for(a=0;a<9;a++)
	{
		start = start + (shou[a] - shou[a+1])*(shou[a] - shou[a+1]);// 之所以相乘两次,是因为我无法解决俩数相减变成负数的问题,惭愧。。。
		end = end + (chuan[a] - chuan[a+1]) * (chuan[a] - chuan[a+1]);// 同上。。。
	}
	start = start + (shou[9] - shou[0]) * (shou[9] - shou[0]); end = end + (chuan[9] - chuan[0])*(chuan[9] - chuan[0]);
	if(start != end )
	{
		printf("\n两个状态的手串无法转换,请检查是否有误!");
		goto game_over;
	}
	for(a=0;shou[a]!=chuan[0]&&a<10;a++) ;
	printf("\n经过计算,最少需要%d次转换才能达到目的!",a);
game_over:
	system("pause");

}

我虽然没实际写过这种代码也没思考过该如何实现,不过你代码提到的那个你没解决的bug我告诉你怎么回事
scanf  是IO函数,基本格式化输入函数,但是这个函数,不会将回车取出来,他把回车放回到缓存区了,所以下次读取会直接吧回车读出来
修改代码

#include <stdio.h>
#include <windows.h>
void main()
{
    char shou[10],chuan[10],c;
	int a,start=0,end=0;
    printf("请输入开始状态的手串:");
	for(a=0;a<10;a++)scanf("%c",&shou[a]);// 最多输入十个字符,然后按下回车,切记!
        //刷输入缓存
	char ch;
       while((scanf("%c",&ch)!=EOF)&&(ch!=""\n""));
	printf("\n请输入结束状态的手串:");
	for(a=0;a<10;a++)scanf("%c",&chuan[a]);

	for(a=0;a<9;a++)
	{
		start = start + (shou[a] - shou[a+1])*(shou[a] - shou[a+1]);// 之所以相乘两次,是因为我无法解决俩数相减变成负数的问题,惭愧。。。
		end = end + (chuan[a] - chuan[a+1]) * (chuan[a] - chuan[a+1]);// 同上。。。
	}
	start = start + (shou[9] - shou[0]) * (shou[9] - shou[0]); end = end + (chuan[9] - chuan[0])*(chuan[9] - chuan[0]);
	if(start != end )
	{
		printf("\n两个状态的手串无法转换,请检查是否有误!");
		goto game_over;
	}
	for(a=0;shou[a]!=chuan[0]&&a<10;a++) ;
	printf("\n经过计算,最少需要%d次转换才能达到目的!",a);
game_over:
	system("pause");

}

还有,这种代码还有 个bug 就是输入10个字符的时候,如果我每输入一个就按一个回车,就可能触发我说的那个问题,下次输入会跳过,直接吧回车读了出来,请注意对用户边界输入情况的处理

谢谢您的指教!我会认真学习的!

5分
引用 5 楼 jack960330 的回复:
Quote: 引用 2 楼 wenpinglaoyao 的回复:

哎,我知道我的代码纯粹是唬人的废物,但看在我这么辛苦的份上,楼主好歹给个关照分吧,谢谢。。。

#include <stdio.h>
#include <windows.h>
void main()
{
    char shou[10],chuan[10],c;
	int a,start=0,end=0;
    printf("请输入开始状态的手串:");
	for(a=0;a<10;a++)scanf("%c",&shou[a]);// 最多输入十个字符,然后按下回车,切记!
	scanf("%c",&c); // 这个BUG我找了很长时间!之所以加上这句话,是为了喝掉那个回车输入!
	printf("\n请输入结束状态的手串:");
	for(a=0;a<10;a++)scanf("%c",&chuan[a]);

	for(a=0;a<9;a++)
	{
		start = start + (shou[a] - shou[a+1])*(shou[a] - shou[a+1]);// 之所以相乘两次,是因为我无法解决俩数相减变成负数的问题,惭愧。。。
		end = end + (chuan[a] - chuan[a+1]) * (chuan[a] - chuan[a+1]);// 同上。。。
	}
	start = start + (shou[9] - shou[0]) * (shou[9] - shou[0]); end = end + (chuan[9] - chuan[0])*(chuan[9] - chuan[0]);
	if(start != end )
	{
		printf("\n两个状态的手串无法转换,请检查是否有误!");
		goto game_over;
	}
	for(a=0;shou[a]!=chuan[0]&&a<10;a++) ;
	printf("\n经过计算,最少需要%d次转换才能达到目的!",a);
game_over:
	system("pause");

}

至于2数相减变成负数,请检查你相减的2个数的大小情况,数学上有这么一种比较方法
C=A-B
如果C 是大于0 则A>B
如果C 小于0 则A<B
所以根据你的注释说明情况,估计你相减的左边的数比右边的数小
至于消除负数的方法,可以进行代码处理变成正数,而不是相乘

嗯嗯,我以前还以为写个【 unsigned(-7) 】就会吧-7变成正7呢,结果昨天晚上电脑告诉我,不会这样。。。

5分
引用 7 楼 wenpinglaoyao 的回复:
Quote: 引用 5 楼 jack960330 的回复:
Quote: 引用 2 楼 wenpinglaoyao 的回复:

哎,我知道我的代码纯粹是唬人的废物,但看在我这么辛苦的份上,楼主好歹给个关照分吧,谢谢。。。

#include <stdio.h>
#include <windows.h>
void main()
{
    char shou[10],chuan[10],c;
	int a,start=0,end=0;
    printf("请输入开始状态的手串:");
	for(a=0;a<10;a++)scanf("%c",&shou[a]);// 最多输入十个字符,然后按下回车,切记!
	scanf("%c",&c); // 这个BUG我找了很长时间!之所以加上这句话,是为了喝掉那个回车输入!
	printf("\n请输入结束状态的手串:");
	for(a=0;a<10;a++)scanf("%c",&chuan[a]);

	for(a=0;a<9;a++)
	{
		start = start + (shou[a] - shou[a+1])*(shou[a] - shou[a+1]);// 之所以相乘两次,是因为我无法解决俩数相减变成负数的问题,惭愧。。。
		end = end + (chuan[a] - chuan[a+1]) * (chuan[a] - chuan[a+1]);// 同上。。。
	}
	start = start + (shou[9] - shou[0]) * (shou[9] - shou[0]); end = end + (chuan[9] - chuan[0])*(chuan[9] - chuan[0]);
	if(start != end )
	{
		printf("\n两个状态的手串无法转换,请检查是否有误!");
		goto game_over;
	}
	for(a=0;shou[a]!=chuan[0]&&a<10;a++) ;
	printf("\n经过计算,最少需要%d次转换才能达到目的!",a);
game_over:
	system("pause");

}

至于2数相减变成负数,请检查你相减的2个数的大小情况,数学上有这么一种比较方法
C=A-B
如果C 是大于0 则A>B
如果C 小于0 则A<B
所以根据你的注释说明情况,估计你相减的左边的数比右边的数小
至于消除负数的方法,可以进行代码处理变成正数,而不是相乘

嗯嗯,我以前还以为写个【 unsigned(-7) 】就会吧-7变成正7呢,结果昨天晚上电脑告诉我,不会这样。。。

不能进行强转,-7变成+1可以-(-7)或者abs(-7)

谢谢各位大神萌,结帖,散分
Ps第一次发帖,还不太会用,不过会散分滴,大家不要急撒~

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明“手环转珠”问题求解
喜欢 (0)
[1034331897@qq.com]
分享 (0)

文章评论已关闭!