题太多了随便写写
A题:暴力,把所有和求一下,然后sort排序输出
#include<iostream>
#include<algorithm>
#include<functional>
using namespace std;
int arr[3006],sum[10000000];
int main()
{
int n,m;
while(scanf("%d %d",&n,&m)!=EOF)
{
for(int i=1;i<=n;++i)
{
scanf("%d",&arr[i]);
}
int t=0;
for(int i=1;i<n;++i)
{
for(int j=i+1;j<=n;++j)
{
sum[++t]=arr[i]+arr[j];
}
}
sort(sum+1,sum+1+t,greater<int>());
printf("%d",sum[1]);
for(int i=2;i<=m;++i)
{
printf(" %d",sum[i]);
}
printf("\n");
}
}
B题STL不解释
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
struct node{
char ch[51];
int score,id;
bool operator <(const node & o)
{
if(score==o.score)return id<o.id;
else return score>o.score;
}
}sp[301],arr[301];
int n;
int main(){
while(scanf("%d",&n)!=EOF)
{
for(int i=1;i<=n;++i)
{
scanf("%s %d",sp[i].ch,&sp[i].score);
sp[i].id=i;
}
for(int i=1;i<=n;++i)
{
scanf("%s %d",arr[i].ch,&arr[i].score);
sp[i].id=i;
}
sort(sp+1,sp+1+n);
int b=0,a=0;
for(int i=1;i<=n;++i){
if(sp[i].score!=arr[i].score){a=1;break;}
else if(strcmp(sp[i].ch,arr[i].ch)!=0){b=1;}
}
if(a==0&&b==0)printf("Right\n");
else if(a==1){
printf("Error\n");
for(int i=1;i<=n;++i)
{
printf("%s %d\n",sp[i].ch,sp[i].score);
}
}
else{
printf("Not Stable\n");
for(int i=1;i<=n;++i)
{
printf("%s %d\n",sp[i].ch,sp[i].score);
}
}
}
}
C题STL不解释
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
struct node{
string id, time;
bool operator<(const node & o)
{
return time<o.time;
}
};
int main()
{
int n;
cin>>n;
while(n--)
{
vector<node>sp;
int t=0,cnt;
cin>>cnt;
for(int i=1;i<=cnt;++i)
{
string ch,tl,t2;
cin>>ch>>tl>>t2;
sp.push_back({ch,tl});
sp.push_back({ch,t2});
}
sort(sp.begin(),sp.end());
cout<<sp.front().id<<" "<<sp.back().id<<endl;
}
}
D题不解释
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
int n,m;
struct node{
string id,name;
int score;
bool operator <(const node & o)
{
if(m==1)return id<o.id;
if(m==2)
{
if(name!=o.name)return name<o.name;
else return id<o.id;
}
if(m==3)
{
if(score!=o.score)return score<o.score;
else return id<o.id;
}
}
};
int main(){
int t=0;
while(scanf("%d %d",&n,&m)&&n!=0&&m!=0)
{
++t;
vector<node> sp;
for(int i=1;i<=n;++i)
{
string a,b;
int c;
cin>>a>>b>>c;
sp.push_back({a,b,c});
}
sort(sp.begin(),sp.end());
printf("Case %d:\n",t);
for(auto i:sp)
{
cout<<i.id<<" "<<i.name<<" "<<i.score<<endl;
}
}
}
E不解释
#include<iostream>
#include<algorithm>
#include<set>
using namespace std;
int main()
{
int n1,n2;
while(scanf("%d %d",&n1,&n2)!=EOF)
{
set<int> p;
for(int i=1;i<=n1;++i)
{
int a;
cin>>a;
p.insert(a);
}
for(int i=1;i<=n2;++i){
int a;
cin>>a;
p.insert(a);
}
int t=1;
for(auto i:p)
{
if(t==1){cout<<i;t=0;}
else cout<<" "<<i;
}
cout<<endl;
}
}
F题:em,就一个点,string要像char一样输出的话要加c_str()函数,感兴趣的自查。哦,还有string能直接比较大小和赋值可真棒。
#include<iostream>
#include<algorithm>
#include<map>
using namespace std;
struct node{
string a,b;
bool operator<(const node & o)const{
{
if(a!=o.a)return a<o.a;
else return b<o.b;
}
}
};
int main(){
int t;
cin>>t;
for(int i=1;i<=t;++i){
map<node,int> mp;
int n;
cin>>n;
for(int i=1;i<=n;++i)
{
string a,b;
int d;
cin>>a>>b>>d;
mp[{b,a}]+=d;
}
string t1="";
for(auto i:mp)
{
if(t1!=i.first.a){t1=i.first.a;cout<<t1<<endl;}
printf(" |----%s(%d)\n",i.first.b.c_str(),i.second);
}
if(i!=t)cout<<endl;
}
}
G:map
#include<iostream>
#include<algorithm>
#include<map>
using namespace std;
int main()
{
int t;
cin>>t;
while(t--){
int n;
cin>>n;
map<int,int> mp;
for(int i=1;i<=n;++i)
{
int d;
cin>>d;
if(mp[d])continue;
else if(i==1){cout<<d;mp[d]=1;}
else {cout<<" "<<d;mp[d]=1;}
mp[d]=1;
}
cout<<endl;
}
}
H:stack
#include<iostream>
#include<algorithm>
#include<stack>
using namespace std;
int main()
{
stack<char> p;
char ch;
int i=1;
while(scanf("%c",&ch)!=EOF)
{
if(ch=='(')p.push(ch);
if(ch==')'){
if(p.empty()){cout<<"NO";i=0;break;}
else p.pop();
}
}
if(i&&p.empty())cout<<"YES";
if(i&&!p.empty()) cout<<"NO";
}
I:贪心+优先队列
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
struct node{
int d;
bool operator <(const node & o)const{
return d>o.d;
}
};
int main()
{
int n;
cin>>n;
while(n--)
{
priority_queue<node> p;
int t;
int ans=0;
cin>>t;
for(int i=1;i<=t;++i)
{
int d;
cin>>d;
p.push({d});
}
while(p.size()!=1)
{
int sum=0;
ans+=p.top().d;
sum+=p.top().d;
p.pop();
ans+=p.top().d;
sum+=p.top().d;
p.pop();
p.push({sum});
}
cout<<ans<<endl;
}
}
J:差分,可用离散化,但我没用,这道题的关键是啥,就是如何压缩空间,所以其实离不离散化无所谓,你只要想办法搞定都可以做,我用的pair来做的
#include<iostream>
#include<algorithm>
#define ll long long int
using namespace std;
int n,t;
pair<ll,ll> pii[400006];
ll sum[400006];
void init()
{
for(int i=1;i<=n;++i)
{
ll a,b;
cin>>a>>b;
pii[++t].first=a;
pii[t].second=1;
pii[++t].first=b+1;
pii[t].second=-1;
}
sort(pii+1,pii+1+t);
}
void solve()
{
int cnt=0;
for(int i=1;i<=t;++i)
{
cnt+=pii[i].second;
if(pii[i].first!=pii[i+1].first)sum[cnt]+=pii[i+1].first-pii[i].first;
}
}
int main()
{
cin>>n;
init();
solve();
cout<<sum[1];
for(int i=2;i<=n;++i)
{
cout<<" "<<sum[i];
}
return 0;
}
K:数组存数然后求中位数,或者map边存边计数都可,前面920ms,后者980ms左右。
数组求中位数
#include<iostream>
#include<map>
#include<algorithm>
using namespace std;
int arr[1000006]={0};
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
int m,t=0;
for(int i=1;i<=n;++i){
cin>>arr[i];
}
sort(arr+1,arr+1+n);
cout<<arr[(n+1)/2]<<endl;
}
}
map边存边计数
#include<iostream>
#include<map>
#include<algorithm>
using namespace std;
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
int m,t=0;
map<int,int> mp;
for(int i=1;i<=n;++i){
int d;
cin>>d;
if(t)continue;
mp[d]++;
if(mp[d]>=(n+1)/2){m=d;t=1;}
}
cout<<m<<endl;
}
}
L:优先队列,当队列中石头数为1的时候结束循环,然后用当时的位置加上自己可以丢的距离(因为本题是奇数次操作丢石头,偶数次直接跳过,只剩1的时候一定是奇数次操作)。
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
struct node{
int s,d;
bool operator <(const node &o)const{
if(s!=o.s)return s>o.s;
return d>o.d;
}
};
int main()
{
int t;
cin>>t;
while(t--){
int n;
cin>>n;
priority_queue<node> p;
for(int i=1;i<=n;++i){
int a,b;
cin>>a>>b;
p.push({a,b});
}
int cnt=0;
while(p.size()>1){
node k=p.top();
p.pop();
if((++cnt)%2==1)p.push({k.s+k.d,k.d});
}
cout<<p.top().s+p.top().d<<endl;
}
}
M:第三次了,老一批谁还不会直接打死
#include<iostream>
#include<set>
using namespace std;
int main()
{
int t;
cin>>t;
for(int j=1;j<=t;++j){
int n,m,k;
cin>>n>>m>>k;
multiset<int> p;
for(int i=1;i<=n;++i)
{
int d;
cin>>d;
p.insert(d);
}
printf("Case %d:\n",j);
for(int i=1;i<=m;++i)
{
int d;
cin>>d;
multiset<int>::iterator t=p.lower_bound(d);
if(t!=p.end()&&*t-d<=k){cout<<*t<<endl;p.erase(t);}
else cout<<-1<<endl;
}
}
}
N和O另一篇上写过了,这里就不写了
P题:l,r代表区间的左端和右端,ans记录当前区间和。从左往右加,和为负数,就更新l,ans初始化为0。这题可以用DP,但是其实体现的还是这个思路,所以感觉没必要。
#include <iostream>
#include <algorithm>
#define M 100006
using namespace std;
int arr[M];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;++i)
{
int t,l=1,r=1,a,b,sum=-2000,ans=0;
cin>>t;
for(int i=1;i<=t;++i)
{
cin>>arr[i];
ans+=arr[i];
if(ans>sum){a=l;b=r;sum=ans;}
if(ans<0){l=i+1;ans=0;}
r=i+1;
}
printf("Case %d:\n",i);
printf("%d %d %d\n",sum,a,b);
if(i!=n)cout<<endl;
}
}