https://vjudge.net/problem/UVA-10129
统计首末字符的熟练,类似于“七桥问题”,根据数量来判断。
存在的问题:
1. 像aa,bb这样的例子是不可以的,但是的打补丁
2,像ab,ba,是可以的,但是不存在数量为奇数的首末字母
3. 多次补丁,通过了所有的测试例子,但是还是WA。
4.Runtime Error的原因是返回了1,应返回0.
#include<iostream>
#include<cstdio>
#include<string.h>
#include<vector>
using namespace std;
int info[2][28];//记录出度和 入度
int iconnect[28][28];
char s[1005];
char c1,c2;
vector<string> vs;
int main() {
void dfs(int istart);
int N,T,okN;;
cin>>T;
while(T--) {
cin>>N;
bool res=true;
okN=N;
memset(info,0,sizeof(info));
memset(iconnect,0,sizeof(iconnect));
for(int i=0; i<N; i++) {
scanf("%s",s);
//gets(s);
c1=s[0];
c2=s[strlen(s)-1];
if(c1==c2) {
okN--;
continue;
}
if(c1-'a'<26&&c1-'a'>=0&&c2-'a'<26&&c2-'a'>=0) {
info[0][c1-'a']++;
info[1][c2-'a']++;
iconnect[c1-'a'][c2-'a']++;
}
}
if(N==1) {
vs.push_back("Ordering is possible.");
cout<<"Ordering is possible."<<endl;
continue;
}
if(okN==0) res=false;
int a_1=0,a1=0;
int istart=0;
int isnotzero=0;
for(int i=0;i<26;i++)
{
if(info[0][i]) isnotzero=i;
int temp=info[1][i]-info[0][i];
//cout<<temp<<endl;
if(temp)
{
if(temp==-1) {a_1++; istart=i; }
else if(temp==1) a1++;
else
{
res=false;
break;
}
}
}
if(!istart) istart=isnotzero;
if((a_1==0&&a1==0)||(a_1==1&&a1==1))
{
}else res=false;
dfs(istart);
for(int i=0;i<26;i++)
{
if(info[1][i]||info[0][i])
{
res=false;
break;
}
}
if(res) {
//vs.push_back("Ordering is possible.");
cout<<"Ordering is possible."<<endl;
} else {
//vs.push_back("The door cannot be opened.");
cout<<"The door cannot be opened."<<endl;
}
//for(int i=0;i<vs.size();i++)
//cout<<vs[i]<<endl;
}
return 0;
}
void dfs(int istart) {
if(istart<0||istart>=26||!info[0][istart])
return ;
for(int i=0; i<26; i++) {
if(iconnect[istart][i]>0) {
info[0][istart]--;
iconnect[istart][i]--;
info[1][i]--;
dfs(i);
}
}
}
正确的
#include<bits/stdc++.h>
using namespace std;
bool vis[26];
int in[26], out[26];//记录出度和 入度
int Map[28][28];
int main()
{
void dfs(int istart);
int N,T;
cin>>T;
while(T--)
{
cin>>N;
char C[1100];
memset(in,0,sizeof(in));
memset(out,0,sizeof(out));
memset(Map,0,sizeof(Map));
for(int i=0;i<N;i++)
{
cin >> C;
int len = strlen(C);
++Map[C[0]-'a'][C[len-1]-'a'];//首尾字母相同的单词总数
++out[C[0]-'a'];//首字母的出度
++in[C[len-1]-'a']; //尾字母的入度
}
int a = 0, b = 0;
bool flag = true;
for(int i = 0; i < 26; i++)
{
if(in[i] != out[i]) //入度不等于出度
{
if(in[i]== out[i]+1) a++;//入度大的点(可能终点)个数
else if(in[i]+1 == out[i]) b++; //出度大的点(可能起点)个数
else{
flag = false; break; //入度和出度相差超过1 这样的图肯定不行
}
}
}
if(a&&b&&a+b>2) flag = false; //奇点多余两个 这样的图不行
if(flag) //到这里flag仍然为真,则说明满足了度数性质,接下来只要看是否连通就行了
{
memset(vis, false, sizeof(vis));
if(2 == a+b) {//这时就应该从出度大于入度的奇点出发 (奇点成对出现)
for(int i = 0; i < 26; i++) {
if(out[i] && 1==(out[i]-in[i])) {
dfs(i); break;
}
}
}
else //
for(int i = 0; i < 26; i++)
{
if(out[i]) {
dfs(i); break;
}
}
bool flag1 = true;
for(int j = 0; j < 26; j++) //凡是已经出现的点中还有没有访问过的
{//就说明不连通
if(in[j]&&!vis[j]) {
flag1 = false; break;
}
if(out[j]&&!vis[j]) {
flag1 = false; break;
}
}
if(flag1) cout << "Ordering is possible."<< endl;
else cout << "The door cannot be opened." << endl;
}
else cout << "The door cannot be opened." <<endl;
}
return 0;
}
void dfs(int k)
{
vis[k] = true;
for(int i = 0; i < 26; i++)
{
if(Map[k][i] && !vis[i]) dfs(i);
}
}