目的:写评价系统,通过过去的表现,预测用户接下来的操作。
输入:
N <=50000 查询数目
K <= 10 最多的评价个数
然后是
输出:
赋值:几个预测值
算法:
边输入边输出。第一个单独处理。
用一个hash表存,出现的次数。
完事排序。
unordered_map + 数组+排序,排序不是对所有元素排序,而是对前K个元素排序。时间复杂度为n。但是有某个测试点出错,至今未找到原因。
#include<stdio.h>
#include<algorithm>
#include<unordered_map>
using namespace std;
int N,K;
unordered_map<int,int> hash1;
int cnt[10] = {0};//记录里面出现最多的标号
int mincnt,num;//mincnt为里面最后一个标号出现的次数,num为里面有效数值为多少个;
bool cmp(int a,int b)
{
if(hash1[a]!=hash1[b])
{
return hash1[a]>hash1[b];
}else
{
return a<b;
}
}
int main()
{
scanf("%d%d",&N,&K);
int v;
scanf("%d",&v);
hash1[v] = 1;
cnt[0] = v;
mincnt = 1;
num = 1;
for(int i=1;i<N;i++)
{
scanf("%d",&v);
printf("%d:",v);
for(int j=0;j<num&&j<K;j++)
{
printf(" %d",cnt[j]);
}
printf("\n");
if(hash1[v]==0)
{
hash1[v] = 1;
if(num<K)
{
cnt[num++] = v;
}else if(hash1[v]==mincnt&&cnt[num-1]>v)
{
cnt[num-1] = v;
}
}else
{
hash1[v]++;
if(hash1[v]==mincnt&&cnt[num-1]>v)
{
cnt[num-1] = v;
}else if(hash1[v]==mincnt+1&&cnt[num-1]<v)
{
cnt[num-1] = v;
}
}
sort(cnt,cnt+K,cmp);
}
return 0;
}
unordered_map+数组+排序,排序每次复杂度nlog n,每插入一个元素,排序一次,复杂度n^2log n,远没有用map,set排序快,用set复杂度nlog n;
#include<stdio.h>
#include<unordered_map>
#include<algorithm>
using namespace std;
const int maxn = 50010;
int N,K;
unordered_map<int,int> q;
int l[maxn];
int cnt = 0;
bool cmp(int a,int b)
{
if(q[a]!=q[b])
{
return q[a]>q[b];
}else
{
return a<b;
}
}
int main()
{
scanf("%d%d",&N,&K);
int u;
scanf("%d",&u);
q[u] = 1;
l[cnt++] = u;
for(int i=1;i<N;i++)
{
scanf("%d",&u);
printf("%d:",u);
for(int j=0;j<cnt&&j<K;j++)
{
printf(" %d",l[j]);
}
printf("\n");
if(q[u]==0)
{
l[cnt++] = u;
}
q[u]++;
sort(l,l+cnt,cmp);
}
return 0;
}
Hash+Set+unordered_map类型
#include<stdio.h>
#include<set>
#include<unordered_map>
using namespace std;
const int maxn =100000;
unordered_map<int,int> q;
set<int,greater<int> > book;
int N,K;
int main()
{
scanf("%d%d",&N,&K);
int u;
scanf("%d",&u);
q[u] = 1;
book.insert(q[u]*maxn-u);
for(int i=1;i<N;i++)
{
scanf("%d",&u);
printf("%d:",u);
int num = 0;
for(set<int>::iterator it = book.begin();it!=book.end()&&num<K;it++,num++)
{
printf(" %d",(maxn-(*it)%maxn));
}
printf("\n");
set<int>::iterator it1 = book.find(q[u]*maxn-u);
if(it1!=book.end())
{
book.erase(it1);
}
if(q[u]==0)
{
q[u] = 1;
}else
{
q[u]++;
}
book.insert(q[u]*maxn-u);
}
return 0;
}
unordered_map+set+小于号的重载 set里面的元素键值不能修改
#include<stdio.h>
#include<set>
#include<unordered_map>
using namespace std;
const int maxn =100000;
struct node{
int data;
int cnt;
bool operator < (const node &a) const{
return (cnt!=a.cnt)?cnt>a.cnt:data<a.data;
}
};
unordered_map<int,int> q;
set<node> book;
int N,K;
int main()
{
scanf("%d%d",&N,&K);
int u;
scanf("%d",&u);
q[u] = 1;
book.insert(node{u,1});
for(int i=1;i<N;i++)
{
scanf("%d",&u);
printf("%d:",u);
int num = 0;
for(set<node>::iterator it = book.begin();it!=book.end()&&num<K;it++,num++)
{
printf(" %d",it->data);
}
printf("\n");
set<node>::iterator it1 = book.find(node{u,q[u]});
if(it1!=book.end())
{
book.erase(it1);
}
if(q[u]==0)
{
q[u] = 1;
}else
{
q[u]++;
}
book.insert(node{u,q[u]});
}
return 0;
}
反思: stl,用得不熟,题目难懂。