继续复习
暴力
题意:输入有点恶心,首先是case数,然后一个空行,然后再输入信息,然后又以一个空行结束该组数据,如果是最后一组数据了,不以空行结束,而是直接以EOF结束。输出,case之间有一个空行,最后一个case后面不要加空行
每组case的信息,就是N行的串,串中只有01,串的个数一定是偶数。原本有很多个一样的长串,每个长串都分成了两个短串但是分割的位置不一定相同即两个短串不一定是平分的(就是输入中的那些串)。你要把这偶数个短串拼回那个长串(即2N个短串拼回N个相同的长串),如果有多种可能,任意一种即可,然后输出这个长串
题目保证一定有有解的
数据不大,144,直接暴力。首先按短串的长度升序排序,然后我们知道,长串的长度 = 最短的短串长度 + 最长的短串的长度。所以我们枚举最短的串和最长的串来组成一个长串,以这个长串也检验所有的组合,能成功的话立马输出
这题没什么好说的,直接看代码
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define N 310 #define LEN 610 char word[LEN]; struct file { char s[LEN]; int len; }a[N]; int n,L; int cmp(struct file x ,struct file y) { return x.len < y.len; } int BF() { int count = 0; bool used[N]; char str[LEN]; memset(used,false,sizeof(used)); for(int i=0; i<n; i++) if(!used[i]) { int ok = 0; for(int j=n-1; j>i; j--) if(!used[j] && a[i].len + a[j].len == L) { strcpy(str,a[i].s); strcat(str,a[j].s); if( !strcmp(word,str) ) { used[i] = used[j] = true; ok = 1; break; } strcpy(str,a[j].s); strcat(str,a[i].s); if( !strcmp(word,str) ) { used[i] = used[j] = true; ok = 1; break; } } if(!ok) break; count ++; } if(count == (n/2)) return 1; else return 0; } void solve() { int i,j; int ok=0; for(i=0; a[i].len==a[0].len; i++) for(j=n-1; a[j].len==a[n-1].len; j--) { strcpy(word,a[i].s); strcat(word,a[j].s); if(BF()) { ok=1; break; } strcpy(word,a[j].s); strcat(word,a[i].s); if(BF()) { ok=1; break; } } printf("%s\n",word); } int main() { int T; scanf("%d",&T); getchar(); getchar(); while(T--) { n = 0; while(1) { if( !gets(a[n].s) ) break; if( !strcmp(a[n].s , "") ) break; a[n].len = strlen(a[n].s); n++; } sort(a,a+n,cmp); L = a[0].len + a[n-1].len; solve(); if(T) printf("\n"); } return 0; }