可能是昨天的题少了一些,今天的题多了一堆,还疯狂TLE /(ㄒoㄒ)\~~
No. | Title | AC/Submit |
---|---|---|
A | 明明的随机数-set | 60/101 |
B | 第K小整数-SET | 57/89 |
C | 单词记忆-set-map | 55/63 |
D | 列车调度-SET | 32/67 |
E | 相似的数集简单版-SET | 31/88 |
F | NOIP 题海战-SET-1 | 10/64 |
G | 指数序列-set | 28/44 |
算是 set 模板题吧,熟悉熟悉 set 和它的迭代器用法。
利用 set 的不重复+有序特性,直接插入 set 即可。
#include
using namespace std;
int main()
{
set<int>s;
int n,i,x;
while(cin>>n)
{
s.clear();
for(i=1;i<=n;i++)
{
cin>>x;
s.insert(x);
}
printf("%d\n",s.size());
for(set<int>::iterator it=s.begin();it!=s.end();it++)
{
if(it!=s.begin())printf(" ");
printf("%d",*it);
}
printf("\n");
}
return 0;
}
这个题其实在迭代器中计数就可以了,可以不折腾到数组里。
#include
using namespace std;
int main()
{
set<int>s;
int ans[10000];
int n,i,x,an,k;
while(cin>>n>>k)
{
an=0;
s.clear();
for(i=1;i<=n;i++)
{
cin>>x;
s.insert(x);
}
for(set<int>::iterator it=s.begin();it!=s.end();it++)
{
ans[an++]=*it;
}
if(k<=an&&k>0)printf("%d\n",ans[k-1]);
else printf("NO RESULT\n");
}
return 0;
}
没什么难度,签到题 +1。
#include
using namespace std;
int main()
{
set<string>s;
int n,o;
string word;
cin>>n;
while(n--)
{
cin>>o>>word;
if(o==0)
{
s.insert(word);
}
else
{
if(s.count(word))printf("YES\n");
else printf("NO\n");
}
}
return 0;
}
这个题有点难度,分析一下题目。
入口有一堆列车 {8,4,2,5,3,9,1,6,7} 按顺序排队进入,要求它们按序号递减的顺序从出去。
首先,必须保证任何时刻 每个铁轨中的列车一定是升序的(编号从小到大),这样才能保证编号大的列车能先出去。
因此,只需要 记录每条铁轨上最后一辆列车的编号,如果 要进入的列车编号小于已有铁轨上末尾列车编号,那么这趟列车可以直接进入这条轨道。如果 要进入的列车编号大于所有铁轨上末尾列车编号,那么就需要另开一条轨道了。
#include
using namespace std;
int main()
{
set<int>s;
set<int >::iterator it;
int n,tmp;
cin>>n;
while(n--)
{
cin>>tmp;
if(s.empty())s.insert(tmp);
else
{
it=s.lower_bound(tmp);
if(it==s.end())s.insert(tmp);
else
{
s.erase(it);
s.insert(tmp);
}
}
}
cout<<s.size();
return 0;
}
这个题不知道为啥 TLE 了好几次,估计是最开始思路有点问题吧。
最后通过的版本没有采用 set 的方法去重,而是选择了数组+unique的方法。
这个题正宗方法应该是 set 吧。
#include
using namespace std;
int main()
{
int arr[50][5001];
double ans[50][50]={0},r;
int n,num,s1,s2,same,tmp,diff,pos;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d",&arr[i][5000]);
for(int j=0;j<arr[i][5000];j++)
{
scanf("%d",&arr[i][j]);
}
sort(arr[i],arr[i]+arr[i][5000]);
arr[i][5000]=unique(arr[i],arr[i]+arr[i][5000])-arr[i];
}
scanf("%d",&n);
while(n--)
{
scanf("%d %d",&s1,&s2);
if(ans[s1-1][s2-1]!=0)
{
printf("%.2f%\n",ans[s1-1][s2-1]);
continue;
}
same=diff=0;
for(int i=0;i<arr[s2-1][5000];i++)
{
pos=lower_bound(arr[s1-1],arr[s1-1]+arr[s1-1][5000],arr[s2-1][i])-arr[s1-1];
if(pos<=arr[s1-1][5000]&&arr[s1-1][pos]==arr[s2-1][i])same++;
}
r=same*100.0/(arr[s1-1][5000]+arr[s2-1][5000]-same);
ans[s1-1][s2-1]=ans[s2-1][s1-1]=r;
printf("%.2f%\n",r);
}
return 0;
}
最开始交上去不知道为啥就 RE 了,后来本地测试数据发现不 RE 也会 TLE。
之后借鉴了 czy 大佬的思路,直接去数组里找答案,原来打算处理一下来着。
我这个版本的 set 是学生->题目,大佬的代码是题目->学生,数据范围差不多,怎么存都行。
#include
using namespace std;
int n,m,p,k,num,type,tmp,ok;
set<int>s[1000];
int sp[1000],spp;
int main()
{
scanf("%d %d",&n,&m);
for(int i=0;i<n;i++)
{
scanf("%d",&num);
for(int j=0;j<num;j++)
{
scanf("%d",&tmp);
s[i].insert(tmp);
}
}
scanf("%d",&k);
while(k--)
{
scanf("%d %d",&type,&num);
spp=0;
for (int i=0;i<num;i++)
{
scanf("%d",&tmp);
sp[spp++]=tmp-1;
}
for(int i=1;i<=m;i++)
{
ok=1;
for (int j=0;j<spp;j++)
{
if (type==0&&s[sp[j]].count(i))
{
ok=0;
break;
}
if (type==1&&!s[sp[j]].count(i))
{
ok=0;
break;
}
}
if(ok)printf("%d ",i);
}
printf("\n");
}
return 0;
}
就是昨天的 map 题加了个 set 后缀,详细思路见昨天的 Problem F。
NEFU 大一寒假训练十一(map)2020.02.17
#include
using namespace std;
int main()
{
int n;
long long maxa=0,num,cnt=0,ans;
map<long long,int>ma;
scanf("%lld",&n);
while(n--)
{
scanf("%lld",&num);
ma[num]++;
if(ma[num]==2)
{
for(long long i=num;ma[i]==2;i++)
{
ma[i]-=2;
ma[i+1]++;
}
}
}
for(map<long long,int>::iterator it=ma.begin();it!=ma.end();it++)
{
if(it->second!=0)
{
cnt++;
if(it->first>maxa)maxa=it->first;
}
}
printf("%lld",maxa<cnt?0:maxa-cnt+1);
return 0;
}