22行代码AC,三种解法——例题3-5_环状序列(UVa-1584)

励志用尽量少的代码做高效表达


题目(提交)链接——>Uva-1584


因为是水题,因此做题重心由解题转向优化

核心思路:

本题共有三种解法:
解法一、string字符串中assign()+erase()截取字符串模拟循环
 大概思路是利用assign()赋值序列的前半部分,用一中间变量保存,同时用erase()删除前半部分,将后半部分与中间变量连接,就是一条新链,循环取字典序最小者
解法二、取余模拟循环(书中解法)
 大概思路就是利用取余将序列从逻辑上连接起来,每次从头逐个比较序列,保存较小的,最后输出。
解法三、循环链表求解
物理上将序列首尾相连,效率低,编写较麻烦,不推荐。


解法一源码:

#include
using namespace std;
int main() {
	int n; cin >> n; while(n--) {
		string sTruely;				//存放输入串 
		string sMin;				//存放最小的字典序表示 
		string sTemporary;			//等于输入串,做临时变量 
		cin >> sTruely; 			//输入 
		sMin = sTruely;				//最小字典序串设初始值 
		int len = sTruely.length();	
		for(int i = 1; i < len; i++) {
			sTemporary = sTruely;	//临时变量代替输入串 
			string t; 
			t.assign(sTemporary,0,i);	//串t赋给前i位 
			sTemporary.erase(0,i);		//临时变量删除前i位 
			t = sTemporary+t;			//串t=临时变量+串t 
			if(sMin > t)  sMin = t;		//判断 
		}
		cout << sMin << '\n';
	} 
	return 0;
} 

解法二注意事项:

这里我用C++写法将书中源码敲了一遍,可奇怪的是,总是弹出错误:

但反复检查,除了我使用了C++的写法,其他与书中代码并无出入,真是人间迷惑?(⊙_⊙)?
最后发现问题出在函数名less中, 命名空间using namespace std;中包含less关键字,导致C++无法编译成功。 将less改为Less方通过编译。

解法二代码:

#include
#define maxn 105
using namespace std;
char s[maxn];
bool Less(const char* s, int p, int q) {		  //p为i,q为ans 
	int n = strlen(s);
	for(int i = 0; i < n; i++) 
		if(s[(p+i)%n] != s[(q+i)%n]) 
			return s[(p+i)%n] < s[(q+i)%n];
	return 0;			//相等 
}
int main() {
	int T;  cin >> T; while(T--) {
		cin >> s;
		int ans = 0, n = strlen(s);
		for(int i = 1; i < n; i++) 
			if(Less(s, i, ans)) ans = i;		//比较首字母,若后者首字母较小,ans记录后者位置。 
		for(int i = 0; i < n; i++) 
			putchar(s[(i+ans)%n]);
		putchar('\n'); 
	}
	return 0;
} 

拨云见日,未来可期22行代码AC,三种解法——例题3-5_环状序列(UVa-1584)_第1张图片

你可能感兴趣的:(算法竞赛与入门经典,数组和字符串)