贪心的水题,一开始没有看清题目,不知道什么时候选择比较长的单词,什么时候应该选择比较短,搞清楚之后,只要单词进行匹配,然后排序(记住要事先记录输出次序)输出
#include <iostream>
#include<string.h>
#include<stdlib.h>
using namespace std;
struct node//用于保存每个单词的信息
{
char word[103];//保存单词
bool f;//记录单词是不是已经访问
int c;//访问前用于保存,单词与上一的匹配个数,访问后用于保存输出的顺序
};
int cmp_c(const void *a,const void *b)//用于qsort的比较函数,主要是确定输出的顺序
{
node *i = (node*)a;
node *j = (node*)b;
return i->c - j->c;
}
node a[2000];//单词的总数
int count;
int n;
void findsame(char *);//寻找配对数
int main()
{
int t,i,j,max,num ,k;
char *ch;
cin >> t;
for(k = 0; k < t; k++)//case的个数
{
count = 0;
cin >> n;
for(j = 0; j < n; j++)//输入每个单词//对信息进行初始化
{
a[j].c = 0;
a[j].f = 0;
cin >> a[j].word;
}
//qsort(a+1,n,sizeof(a[0]),cmp_word);
num = 1;//记录已经访问的单词个数
j = 1;
ch = a[0].word;
count = strlen(a[0].word);
a[0].f = 1;
a[0].c = 0;
findsame(ch);//对第一个单词进行处理
while(num < n)//判断是否已经把所有的单词都已经搜索完毕
{
max = 0;
for(i = 0; i < n; i++)//寻找与上一个单词最相似的
{
if(!a[i].f&& max < a[i].c )//还没有被访问,并且相同的个数比当前最大
{
max = a[i].c;
j = i;
}
}
if(max == 0 && num < n)//如果字母相同的个数都是零,怎找长度最长的
//如果都没有与上一个单词匹配的,则找出一个还没与被访问过的比较长的单词
{
for(i = 0;i < n; i++)
{
if(!a[i].f && max < strlen(a[i].word))
{
max = strlen(a[i].word);
j = i;//记录max所对应的元素是那个
}
}
}
ch = a[j].word;//找到最佳单词
count += strlen(a[j].word) - a[j].c;//要按键的次数
a[j].f = 1;
a[j].c = num;
findsame(ch);
num++;
}
cout << count << endl;
qsort(a,n,sizeof(a[0]),cmp_c);
for(i = 0; i < n; i++)
{
// cout << a[i].c << endl;
cout << a[i].word << endl;
}
}
return 0;
}
void findsame(char *t)
{
int len1,len2,i,j;
len1 = strlen(t);
for(i = 1; i < n; i++)
{
if(!a[i].f)
{
len2 = strlen(a[i].word);
a[i].c = 0;
for(j = 0;j < len2 && j < len1; j++)
{
if(t[j] == a[i].word[j])
{
a[i].c++;
}
else
break;
}
}
}
}