• vijos1287确定的位置


    题目:https://vijos.org/p/1287

    解:

    啊,又不会。。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<map>
    using namespace std;
    inline int read()
    {
      char ch; int ef=0;
      ch=getchar();
      while ((ch<'0')||(ch>'9')) ch=getchar();
      while ((ch>='0')&&(ch<='9')) 
      {
          ef=ef*10+ch-'0';
          ch=getchar();
      }
      return ef;
    }
    map<string,int>maxs;
    //maxs[s]表示s这首歌当前可能的最大(数字最大)的名次是多少
    int n,tot,newt[2000],sum[2000];
    string s,name[2000],ans[2000];
    int main()
    {
      scanf("%d",&n);
      for (int i=1;i<=n;i++)
      {
          int a=read(); cin>>s; int b=read(); 
          for (int j=1;j<=a;j++)
          {
            cin>>s;
    //newt[b]从目前已给的信息中我们可以知道前b名比前面的名次多出现了几首歌
            if (maxs[s]==0) maxs[s]=b,name[++tot]=s,newt[b]++;
    //如果当前这首歌是第一次出现,那么用name记录下歌曲的名字,当前s这首歌最大的名次为b,且前b名中又出现了一首新的歌,所以new[b]++;
            else if (maxs[s]>b) newt[maxs[s]]--,maxs[s]=b,newt[b]++;
    //如果说这首歌在前面所给的信息中出现过了,且前面出现时给的范围是前maxs[s]名,且maxs[s]>b,则说明这首歌在前b名中就出现过了new[b]++,在前maxs[s]名中已经不是一首新歌了,maxs[s]--;同时更新s这首歌的最大名次是b
        }
      }
      for (int i=1;i<=tot;i++) sum[i]+=sum[i-1]+newt[i];
    //表示在前i名中出现了几首歌,如sum[2]=1,则表示前两名中,已经告诉我们了其中一首歌的名字。
      for (int i=1;i<=tot;i++) ans[maxs[name[i]]]=name[i];
    如果name[i]这首歌可以确定名次,那么它的名次一定是maxs[name[i]];
      for (int i=1;i<=tot;i++)
      if ((newt[i]==1)&&(sum[i]==i)) cout<<i<<" "<<ans[i]<<endl;
    //如果第i个名次的歌曲可以确定,那么首先sum[i]要等于i即前i名的歌曲名都要给出且newt[i]=1即前i名与前面的名次相比,在给出的歌曲中出现了一首新歌,那么这首新歌就一定是第i名
      return 0;
    }
  • 相关阅读:
    ps命令
    关于typedef的用法总结
    C#中正则表达式的使用
    调试与编译
    大端和小端
    64位程序内存之我看
    C/C++内存泄漏及检测
    内核中的 likely() 与 unlikely()
    do/while(0) c4127
    django+xadmin在线教育平台(六)
  • 原文地址:https://www.cnblogs.com/2014nhc/p/7058257.html
Copyright © 2020-2023  润新知