Summary
可能是昨天的題少了一些,今天的題多了一堆,還瘋狂TLE /(ㄒoㄒ)\~~
Information
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 |
Problem A: 明明的隨機數-set (743) [60/101]
Tips
算是 set 模板題吧,熟悉熟悉 set 和它的迭代器用法。
利用 set 的不重複+有序特性,直接插入 set 即可。
Code
#include <bits/stdc++.h>
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;
}
Problem B: 第K小整數-SET (1684) [57/89]
Tips
這個題其實在迭代器中計數就可以了,可以不折騰到數組裏。
Code
#include <bits/stdc++.h>
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;
}
Problem C: 單詞記憶-set-map (2117) [55/63]
Tips
沒什麼難度,簽到題 +1。
Code
#include <bits/stdc++.h>
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;
}
Problem D: 列車調度-SET (1680) [32/67]
Tips
這個題有點難度,分析一下題目。
入口有一堆列車 {8,4,2,5,3,9,1,6,7} 按順序排隊進入,要求它們按序號遞減的順序從出去。
首先,必須保證任何時刻 每個鐵軌中的列車一定是升序的(編號從小到大),這樣才能保證編號大的列車能先出去。
因此,只需要 記錄每條鐵軌上最後一輛列車的編號,如果 要進入的列車編號小於已有鐵軌上末尾列車編號,那麼這趟列車可以直接進入這條軌道。如果 要進入的列車編號大於所有鐵軌上末尾列車編號,那麼就需要另開一條軌道了。
Code
#include <bits/stdc++.h>
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;
}
Problem E: 相似的數集簡單版-SET (2119) [31/88]
Tips
這個題不知道爲啥 TLE 了好幾次,估計是最開始思路有點問題吧。
最後通過的版本沒有采用 set 的方法去重,而是選擇了數組+unique的方法。
這個題正宗方法應該是 set 吧。
Code
#include <bits/stdc++.h>
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;
}
Problem F: NOIP 題海戰-SET-1 (1679) [10/64]
Tips
最開始交上去不知道爲啥就 RE 了,後來本地測試數據發現不 RE 也會 TLE。
之後借鑑了 czy 大佬的思路,直接去數組裏找答案,原來打算處理一下來着。
我這個版本的 set 是學生->題目,大佬的代碼是題目->學生,數據範圍差不多,怎麼存都行。
Code
#include <bits/stdc++.h>
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;
}
Problem G: 指數序列-set (1677) [28/44]
Tips
就是昨天的 map 題加了個 set 後綴,詳細思路見昨天的 Problem F。
NEFU 大一寒假訓練十一(map)2020.02.17
Code
#include <bits/stdc++.h>
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;
}