题意:N个小朋友,告诉你他们的朋友关系。K次询问,对每次询问回答有几种告白方式。告白的方法是——A喜欢B,那么A要找邻接点C,C找邻接点D,D告诉他的朋友B实现告白。要求A和B同性别,C和D同性别,A和B不一定。人数N小于300,询问K小于100.输出所有可行的C和D,按照升序输出。
思路:思路可以想到,列举一下A的所有朋友,列举一下B的所有朋友,然后看看他们各自的朋友有几对朋友即可。但是我写的太慢太复杂了。。。晕死,也懒得改了。
难点:这题的按照上书写了之后只拿到20分。。。我也没想到啥原因。看了柳神的博客学习之后,恍然大悟,发现本题有两个细节情况必须要讨论!
1、判断性别的时候如果ID是0000,按照数字读入就会没办法判断此人的性别。所以只能用字符串输入的形式。这样就能过第二个样例,多得4分。
2、A要像B告白的话,在建A的朋友列表的时候,必须要排除B。。。这个点考虑就能过另外三个点,加6分。
本题考查编码习惯、思考细节方面很不错,码一下留个纪念。
Code:
#include<bits/stdc++.h>
#include<unordered_map>
using namespace std;
#define inf 309
#define INF 0x3f3f3f3f
#define loop(x,y,z) for(x=y;x<z;x++)
int n,m,k;
unordered_map<int,int>mp;
unordered_map<int,int>mp2;
bool isboy[inf];
int e[inf][inf];
int stoi(string &s1)//Codeblocks不支持,手写一下
{
const char *s=s1.c_str();
int len=s1.length();
int flag=1;
if(s1[0]=='-')flag=0;
int sum=0,i=0;
if(!flag)i++;
for(i;i<len;i++)
sum=sum*10+s[i]-48;
if(!flag)sum*=-1;
return sum;
}
bool cmp(pair<int,int>&x,pair<int,int>&y)
{
if(mp2[x.first]==mp2[y.first])return mp2[x.second]<mp2[y.second];
return mp2[x.first]<mp2[y.first];
}
void findAns(int x,int y)
{
int sum=0,i,j;
vector<int>left;
left.clear();
vector<int>right;
right.clear();
vector< pair<int,int> >ans;
ans.clear();
loop(i,1,n+1)if(e[x][i]&&i!=y&&isboy[x]==isboy[i])left.push_back(i);
loop(i,1,n+1)if(e[y][i]&&i!=x&&isboy[y]==isboy[i])right.push_back(i);
loop(i,0,left.size())
loop(j,0,right.size())
{
int u=left[i];
int v=right[j];
if(e[u][v]&&((isboy[x]==isboy[y]&&isboy[u]==isboy[v])||(isboy[x]!=isboy[y]&&isboy[u]!=isboy[v])))
{
sum++;
ans.push_back(pair<int,int>(u,v));
}
}
printf("%d\n",sum);
if(!sum)return;
sort(ans.begin(),ans.end(),cmp);
loop(i,0,ans.size())
printf("%04d %04d\n",mp2[ans[i].first],mp2[ans[i].second]);
}
int main()
{
int i,j;
int x,y;
scanf("%d%d",&n,&m);
int id=1;
loop(i,0,m)
{
bool flag1=1,flag2=1;
string s1,s2;
cin>>s1>>s2;
int x=stoi(s1);
int y=stoi(s2);
if(s1[0]=='-'){flag1=0;x=-x;}
if(s2[0]=='-'){flag2=0;y=-y;}
if(mp.count(x))x=mp[x];
else
{
mp[x]=id;
mp2[id]=x;
x=mp[x];
id++;
}
if(mp.count(y))y=mp[y];
else
{
mp[y]=id;
mp2[id]=y;
y=mp[y];
id++;
}
isboy[x]=flag1;
isboy[y]=flag2;
e[x][y]=e[y][x]=1;
}
scanf("%d",&k);
while(k--)
{
scanf("%d%d",&x,&y);
x=x<0?-x:x;
y=y<0?-y:y;
x=mp[x];
y=mp[y];
findAns(x,y);
}
return 0;
}