爆刷PAT(甲级)——之【1139】 First Contact (30 分)——模拟+两个细节

题意: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
#include
using namespace std;
#define inf 309
#define INF 0x3f3f3f3f
#define loop(x,y,z) for(x=y;xmp;
unordered_mapmp2;
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&x,pair&y)
{
    if(mp2[x.first]==mp2[y.first])return mp2[x.second]left;
    left.clear();
    vectorright;
    right.clear();
    vector< pair >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(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;
}

 

你可能感兴趣的:(PAT甲级【爆刷】)