--------------
A. Amusing Joke
--
前两行的字母恰好组成最后一行
--
#include <iostream>
#include <cstring>
using namespace std;
char a[1111];
int ch[26]={0};
int main()
{
cin>>a;
for (int i=0;a[i];i++){
ch[a[i]-'A']++;
}
cin>>a;
for (int i=0;a[i];i++){
ch[a[i]-'A']++;
}
cin>>a;
for (int i=0;a[i];i++){
ch[a[i]-'A']--;
}
bool flag=true;
for (int i=0;i<26;i++){
if (ch[i]!=0){
cout<<"NO"<<endl;
flag=false;
break;
}
}
if (flag) cout<<"YES"<<endl;
return 0;
}
-------------
B. Hopscotch
----
模拟计算(x,y)所在的格子
公式易推,注意边界
----
#include <iostream>
#include <cstring>
using namespace std;
void solve(int a,int x,int y){
if (y%a==0){
cout<<-1<<endl;
return;
}
int fl=y/a;
if (fl==0){
if (2*x<a&&2*x>-a) cout<<1<<endl;
else cout<<-1<<endl;
return;
}
int nu=(fl+1)/2;
if (fl%2==1){
if (2*x<a&&2*x>-a) cout<<nu*3-1<<endl;
else cout<<-1<<endl;
return;
}
else{
if (x>0&&x<a) cout<<nu*3+1<<endl;
else if (x<0&&x>-a) cout<<nu*3<<endl;
else cout<<-1<<endl;
return;
}
}
int main()
{
int a,x,y;
cin>>a>>x>>y;
solve(a,x,y);
return 0;
}
--------------
C. Queue
---
有n个人排成一队
给出每个人前面比他高的人数
构造一个身高序列
---
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int INF=0x3f3f3f;
const int MAXN=10000;
struct Data{
string name;
int a;
int h;
}f[MAXN];
bool cmp(Data x,Data y){
return x.a<y.a;
}
int n,m;
int main()
{
cin>>n;
for (int i=0;i<n;i++){
cin>>f[i].name>>f[i].a;
}
sort(f,f+n,cmp);
for (int i=0;i<n;i++){
if (f[i].a>i){
cout<<-1<<endl;
return 0;
}
}
m=0;
for (int i=0;i<n;i++){
f[i].h=i+1-f[i].a;
for (int j=0;j<i;j++){
if (f[j].h>=f[i].h) f[j].h++;
}
}
for (int i=0;i<n;i++){
cout<<f[i].name<<" "<<f[i].h<<endl;
}
return 0;
}
--------------
D. Take-off Ramps
----
长度为L的场地里有n个跳板
对位于坐标Xi的跳板,要提前Pi米准备,跳到Di用时Ti。
问从0到L的最短距离。
----
以0、L、Xi-Pi、Xi+Di为顶点构造图。
从0到L的最短路即为所求。
将每个顶点按坐标排序,相邻两个顶点之间建一条长度为两点距离差绝对值的边
跳板两端点间建一条长度为Pi+Ti的边。
距离有可能超过int。
注意输出格式以及时间效率。
--------------
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <map>
#include <cstdio>
using namespace std;
typedef long long LL;
const long long INF=1LL << 60;
const int maxn=500000;
const int maxm=5000000;
struct EdgeNode{
int to;
LL w;
int next;
};/*==============================================*\
| Dijkstra+堆优化
| INIT: init(n);addedge(u,v,c);节点编号0~n
| CALL: dijkstra(int s);dis[]:最短路;pre[]:前驱
\*==============================================*/
struct HeapNode{
LL d;
int u;
HeapNode(){}
HeapNode(LL a,int b):d(a),u(b){}
bool operator<(const HeapNode& rhs) const{
return d>rhs.d;
}
};
struct Dijkstra{
EdgeNode edges[maxm];
int head[maxn];
int edge,n;
void init(int n){
this->n=n;
memset(head,-1,sizeof(head));
edge=0;
}
void addedge(int u,int v,LL c){
edges[edge].w=c,edges[edge].to=v,edges[edge].next=head[u],head[u]=edge++;
}
bool done[maxn];
LL dis[maxn];
int pre[maxn];
void dijkstra(int s){
priority_queue<HeapNode>que;
for (int i=0;i<=n;i++) dis[i]=INF;
dis[s]=0;
memset(done,0,sizeof(done));
que.push(HeapNode(0,s));
while (!que.empty()){
HeapNode x=que.top();
que.pop();
int u=x.u;
if (done[u]) continue;
done[u]=true;
for (int i=head[u];i!=-1;i=edges[i].next){
int v=edges[i].to;
LL w=edges[i].w;
if (dis[v]>dis[u]+w){
dis[v]=dis[u]+w;
pre[v]=u;
que.push(HeapNode(dis[v],v));
}
}
}
}
}G;
struct Data{
int x,d,t,p;
int id;
}a[maxn];
struct POI{
int p;
int id;
POI(){}
POI(int a,int b):p(a),id(b){}
};
vector<POI>vec;
bool cmp(POI a,POI b){
return a.p<b.p;
}
vector<int>ans;
int mp[maxn];
int main()
{
int n,L,m;
memset(mp,-1,sizeof(mp));
scanf("%d%d",&n,&L);
G.init(2*n+1);
m=0;
for (int i=1;i<=n;i++){
scanf("%d%d%d%d",&a[i].x,&a[i].d,&a[i].t,&a[i].p);
a[i].id=i;
G.addedge(i,i+n,a[i].p+a[i].t);
if (a[i].t<a[i].d){
mp[i+n]=i;
}
//cerr<<i<<" "<<i+n<<" "<<a[i].t<<endl;
vec.push_back(POI(a[i].x-a[i].p,i));
vec.push_back(POI(a[i].x+a[i].d,i+n));
}
vec.push_back(POI(L,2*n+1));
vec.push_back(POI(0,0));
sort(vec.begin(),vec.end(),cmp);
for (int i=0;i<(int)vec.size()-1;i++){
if (vec[i].p<0) continue;
G.addedge(vec[i].id,vec[i+1].id,abs(vec[i+1].p-vec[i].p));
G.addedge(vec[i+1].id,vec[i].id,abs(vec[i].p-vec[i+1].p));
//cerr<<vec[i].id<<" "<<vec[i+1].id<<" "<<abs(vec[i+1].p-vec[i].p)<<endl;
}
G.dijkstra(0);
printf("%I64d\n",G.dis[2*n+1]);
int t=2*n+1;
while (t!=0){
if (mp[t]==G.pre[t]) ans.push_back(G.pre[t]);
t=G.pre[t];
}
printf("%d\n",ans.size());
for (int i=(int)ans.size()-1;i>=0;i--){
printf("%d ",ans[i]);
}
printf("\n");
return 0;
}
-------------
E. Clearing Up
--------
有n个节点的图,求最小生成树,要求S与M各占一半。
---------
易知最小生成树有n-1条边,一半为S一半为M
定义两个并查集S1、S2。答案集e1,e2。
保证属于一个集合的顶点中,任意两个顶点之间有且只有一条简单路径。
首先只考虑S边,将S边相连的顶点合并到并查集S1里的一个集合
考虑M边,若最终想要得到一个最小生成树,则并查集S1中必须只有一个集合。
所以枚举所有M边,若某M边能连接S1中不同集合的顶点,则在S1、S2中合并这两个顶点,将该M边加入答案集e1。
如果此时M边不满(n-1)/2,枚举M边,若该边能连接S2中的不同集合则合并这两个集合并将该M边加入答案集e1。
枚举所有S边,若能连接S2中不集合则合并集合并将该S边加入答案集e2。
最终答案集e1中储存的是最小生成树中的M边,e2为S边。并且size(e1)=(n-1)/2。
若size(e1)!=size(e2)则无解。
---------
#include <iostream>
#include <vector>
#include <cstring>
#define sz(x) int(x.size())
using namespace std;
const int maxn=11111;
const int maxm=111111;
struct DisjointSet{
int pa[maxn];
void makeSet(int n){
for (int i=0;i<=n;i++) pa[i]=i;
}
int findSet(int x){
if (x!=pa[x]) pa[x]=findSet(pa[x]);
return pa[x];
}
void unionSet(int x,int y){
x=findSet(x);
y=findSet(y);
if (x!=y) pa[x]=y;
}
}s1,s2;
int n,m;
struct Edge{
int u,v;
char c;
};
Edge vec[maxm];
vector<int> e1,e2;
int d;
int main()
{
cin>>n>>m;
for (int i=0;i<m;i++){
cin>>vec[i].u>>vec[i].v>>vec[i].c;
}
s1.makeSet(n);
s2.makeSet(n);
for (int i=0;i<m;i++){
if (vec[i].c=='S'){
if (s1.findSet(vec[i].u)!=s1.findSet(vec[i].v)){
s1.unionSet(vec[i].u,vec[i].v);
}
}
}
d=(n-1)/2;
for (int i=0;i<m;i++){
if (vec[i].c=='M'){
if (s1.findSet(vec[i].u)!=s1.findSet(vec[i].v)){
s1.unionSet(vec[i].u,vec[i].v);
s2.unionSet(vec[i].u,vec[i].v);
e1.push_back(i);
d--;
}
}
}
for (int i=0;i<m;i++){
if (vec[i].c=='M'&&d>0){
if (s2.findSet(vec[i].u)!=s2.findSet(vec[i].v)){
s2.unionSet(vec[i].u,vec[i].v);
e1.push_back(i);
d--;
}
}
}
for (int i=0;i<m;i++){
if (vec[i].c=='S'){
if (s2.findSet(vec[i].u)!=s2.findSet(vec[i].v)){
s2.unionSet(vec[i].u,vec[i].v);
e2.push_back(i);
}
}
}
d=(n-1)/2;
if (sz(e1)!=d||sz(e2)!=d) cout<<-1<<endl;
else{
cout<<n-1<<endl;
for (int i=0;i<sz(e1);i++){
cout<<e1[i]+1<<" ";
}
for (int i=0;i<sz(e2);i++){
cout<<e2[i]+1<<" ";
}
cout<<endl;
}
return 0;
}
---------
-