2020-2021 ICPC Southwestern European Regional Contest (SWERC 2020)

A. Gratitude

字符串再加上个pair排序即可

#include <bits/stdc++.h>

using namespace std;
#define PII pair<int,int>
#define fi first
#define se second
#define pb push_back
#define ll long long
const int N=1e6+10;

int n,k;
map<string,int> mp,pos;
vector<pair<string,pair<int,int>>> v;
string s;

int main(){
    cin>>n>>k;
    getchar();
    for(int i=1;i<=3*n;++i){
        getline(cin,s);
        mp[s]++;
        pos[s]=i;
    }
    int cnt=0;
    for(auto w:mp){
        v.pb({w.fi,{w.se,pos[w.fi]}});
        cnt++;
    }
    sort(v.begin(),v.end(),[&](pair<string,pair<int,int>> a,pair<string,pair<int,int>> b){
            if(a.se.fi!=b.se.fi) return a.se.fi>b.se.fi;
            return a.se.se>b.se.se;
    });
    for(int i=0;i<min(k,cnt);++i){
        cout<<v[i].fi<<endl;
    }
    return 0;
}

C. Safe Distance

队友写的。。

#include<bits/stdc++.h>
#define x first
#define y second

using namespace std;

typedef pair<double, double> PDD;
const double eps = 1e-6;
const int N = 1e3+10;

double X, Y;
PDD q[N];
int n;
int p[N];
double ans;

int find(int x){
    if(p[x]!=x) return p[x]=find(p[x]);
    return p[x];
}

double get_dist(PDD a, PDD b){
    double dx = a.x - b.x;
    double dy = a.y - b.y;
    return sqrt(dx * dx + dy * dy);
}

int check(double r){
    int v, w;
    for(int i = 1 ;i <= n + 4 ;i++) p[i]=i;
    for(int i = 1; i <= n; i ++){
        if(q[i].x<r){//zuo
            v=find(i); w=find(n+4);
            if(v!=w) p[v]=w;
        }
        if(X - q[i].x < r){//you
            v=find(i), w=find(n+2);
            if(v!=w) p[v]=w;
        }
        if(q[i].y < r){//xia
            v=find(i), w=find(n+3);
            if(v!=w) p[v]=w;
        }
        if(Y - q[i].y < r){//shang
            v=find(i), w=find(n+1);
            if(v!=w) p[v]=w;
        }
        for(int j = i + 1; j <= n ; j++){
            double dis = get_dist(q[i], q[j]);
            if(dis < r * 2){
                v=find(i), w=find(j);
                if(v!=w) p[w]=v;
            }
        }
    }
    if(find(n+1)!=find(n+2) && find(n+1)!=find(n+3) && find(n+3)!=find(n+4) && find(n+2)!=find(n+4)) return 1;
/*    if(find(n+1) == find(n+2)) return -1;
    else if(find(n+1) == find(n+3)) return -1;
    else if(find(n+3) == find(n+4)) return -1;
    else if(find(n+2) == find(n+4)) return -1;
    else return 1;*/
    return -1;
}

int main()
{
    scanf("%lf %lf",&X, &Y);
    scanf("%d",&n);
    for(int i = 1; i <= n;i ++){
        scanf("%lf %lf",&q[i].x, &q[i].y);
    }
    double l = 0, r = max(X, Y);
    while(r - l >= eps){
        double mid = (l + r) / 2;
//        printf("mid=%lf\n",mid);
        if(check(mid)==-1){
            r=mid;
        }else{
            l=mid;
        }
    }
    printf("%lf\n",l);
    return 0;
}

D. Jogging

队友过的,好像就是个最短路板子题

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<algorithm>
#include<iomanip>
#define max(a,b)   (a>b?a:b)
#define min(a,b)   (a<b?a:b)
#define swap(a,b)  (a=a+b,b=a-b,a=a-b)
#define e  2.718281828459045
#define INF 0x3f3f3f3f
#define PI acos(-1)
#define eps 1.0e18
#define lowbit(x) (x&(-x))
#define read(x) scanf("%d",&x)
#define put(x) printf("%d\n",x)
#define memset(x,y) memset(x,y,sizeof(x))
#define Debug(x) cout<<x<<" "<<endl
#define lson i << 1,l,m
#define rson i << 1 | 1,m + 1,r
#define rep(x,y,z) for(int x = y; x <= z; x++)
#define per(x,y,z) for(int x = y; x >= z; x--)
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
ll qpow(ll a,ll b,ll mod){ll res = 1;while(b){if(b&1){res=res*a%mod;}b>>=1;a=a*a%mod;}return res%mod;}
const ll mod = 1e9+7;
const ll maxn = 1e5+5;
vector<pair<int,int>> vec[200000];
priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>> pq;
map<pair<int,int>,int> mp;
bool vis[200000];
int dis[200000];
void dijkstra(int n)
{
    for(int i = 1; i < n; i++){
        dis[i] = 1000000007;
        vis[i] = false;
    }
    dis[0] = 0;
    vis[0] = false;
    pq.push({0,0});
    while(!pq.empty()){
        pair<int,int> p = pq.top();
        pq.pop();
        int id = p.second;
        int d = p.first;
        if(vis[id])continue;
        vis[id] = true;
        for(pair<int,int> u:vec[id]){
            if(dis[u.first]>dis[id]+u.second){
                dis[u.first]=dis[id]+u.second;
                pq.push({dis[u.first],u.first});
            }
        }
    }
}
int main()
{
    ios::sync_with_stdio(false);
    int n,m,l,r;
    cin>>n>>m>>l>>r;
    for(int i = 1,u,v,x; i <= m; i++){
        cin>>u>>v>>x;
        vec[u].push_back({v,x});
        vec[v].push_back({u,x});
    }
    dijkstra(n);
    ll ans = 0;
    for(int i = 0; i < n; i++){
        if(dis[i]*2>=r)continue;
        int len = vec[i].size();
        for(int j = 0; j < len; j++){
            int a = min(i,vec[i][j].first);
            int b = max(i,vec[i][j].first);
            if(mp[{a,b}])continue;
            ans++;
            mp[{a,b}]++;
        }
    }
    cout<<ans<<endl;
    return 0;
}

E. Cakes

签到

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<algorithm>
#include<iomanip>
#define max(a,b)   (a>b?a:b)
#define min(a,b)   (a<b?a:b)
#define swap(a,b)  (a=a+b,b=a-b,a=a-b)
#define e  2.718281828459045
#define INF 0x3f3f3f3f
#define PI acos(-1)
#define eps 1.0e18
#define lowbit(x) (x&(-x))
#define read(x) scanf("%d",&x)
#define put(x) printf("%d\n",x)
#define memset(x,y) memset(x,y,sizeof(x))
#define Debug(x) cout<<x<<" "<<endl
#define lson i << 1,l,m
#define rson i << 1 | 1,m + 1,r
#define rep(x,y,z) for(int x = y; x <= z; x++)
#define per(x,y,z) for(int x = y; x >= z; x--)
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
ll qpow(ll a,ll b,ll mod){ll res = 1;while(b){if(b&1){res=res*a%mod;}b>>=1;a=a*a%mod;}return res%mod;}
const ll mod = 1e9+7;
const ll maxn = 1e5+5;

int main()
{
    ios::sync_with_stdio(false);
    int n;
    cin>>n;
    int ans = 1000000000;
    for(int i = 1,x,y; i <= n; i++){
        cin>>x>>y;
        ans = min(ans,y/x);
    }
    cout<<ans<<endl;
    return 0;
}

H. Figurines

  • 题意:每天可以在一排横着的货架上添加或删去物品,定义:\(x_{i+1}=x_i+y_i\),\(x_0=0\),\(y_i\)表示第\(i\)天货架上不小于\(x_i\)的物品数,给你\(n\)个询问,第\(i\)个询问问你第\(d_i\)天的\(x_i\)值。

  • 题解\(x_i\)是线性得到的,我们唯一需要求的就是第\(d_i\)天时,货架上不小于\(x_i\)的物品数,显而易见,对历史区间查询,主席树即可啦~,注意这题的读入。

  • 代码

    #include <bits/stdc++.h>
    #define ll long long
    #define fi first
    #define se second
    #define pb push_back
    #define me memset
    #define rep(a,b,c) for(int a=b;a<=c;++a)
    #define per(a,b,c) for(int a=b;a>=c;--a)
    const int N = 5e5 + 10;
    const int mod = 1e9 + 7;
    const int INF = 0x3f3f3f3f;
    using namespace std;
    typedef pair<int,int> PII;
    typedef pair<ll,ll> PLL;
    ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
    ll lcm(ll a,ll b) {return a/gcd(a,b)*b;}
     
    int n;
    int root[N],idx;
    int mp[N];
    struct Node{
    	int l,r;
    	int cnt;
    }tr[N<<4];
     
    int build(int l,int r){
    	int p=++idx;
    	if(l==r) return p;
    	int mid=(l+r)>>1;
    	tr[p].l=build(l,mid);
    	tr[p].r=build(mid+1,r);
    	return p;
    }
     
    int update(int p,int l,int r,int x,int k){
    	int q=++idx;
    	tr[q]=tr[p];
    	tr[q].cnt+=k;
    	if(l==r) return q;
    	int mid=(l+r)>>1;
    	if(x<=mid) tr[q].l=update(tr[p].l,l,mid,x,k);
    	else tr[q].r=update(tr[p].r,mid+1,r,x,k);
    	return q;
    }
     
    int query(int u,int l,int r,int x){
    	if(l>=x) return tr[u].cnt;
    	if(l==r) return tr[u].cnt;
    	int mid=(l+r)>>1;
    	int sum=0;
    	if(x<=mid) sum+=query(tr[u].l,l,mid,x);
    	sum+=query(tr[u].r,mid+1,r,x);
    	return sum;
    }
     
    int main() {
    	cin>>n;
    	root[0]=build(1,n);
    	getchar();
    	int cnt=0;
    	for(int i=1;i<=n;++i){
    		string s;
    		getline(cin,s);
    		int num=0;
    		int flag=1;
    		for(int j=0;j<(int)s.size();++j){
    			if(s[j]==' '){
    				cnt++;
    				root[cnt]=update(root[cnt-1],1,n,num,flag);
    				num=0;
    				continue;
    			}
    			if(j==(int)s.size()-1){
    				cnt++;
    				num=num*10+s[j]-'0';
    				root[cnt]=update(root[cnt-1],1,n,num,flag);
    				break;
    			}
    			if(s[j]=='+'){
    				flag=1;
    			}
    			else if(s[j]=='-')flag=-1;
    			else num=num*10+s[j]-'0';
    		}
    		mp[i]=cnt;
    	}
    	int x=0;
    	for(int i=1;i<=n;++i){
    		int d;
    		cin>>d;
    		int res=query(root[mp[d]],1,n,x);
    		x=(x+res)%n;
    	}
    	cout<<x<<endl;
    	return 0;
    }
    

I. Emails

  • 题意:一张图,每个点都可以储存其他的点的信息,每次,每个点会把自己和其他相邻点的信息传给所有相邻的点,问你最少操作多少次使得每个点都储存了其他所有点的信息,允许有+1的误差。

  • 题解:首先手玩几个样例,对于两个点\((u,v)\)不难发现一定在\(\lceil log_2(u->v)\rceil\)次后相互得到对方信息,那么对于整张图的最坏情况为\(\lceil log_2(diam)\rceil\)(直径).现在假设我们任意选一个点出发,其最远路径为\(D\),那么有:

    \(1.D\le diam\le 2*D\).

    \(2.\log(D)\le \log(diam)\le \log(2*D)+1\)

    \(3.log(diam)\le\log(2*D)+1\le\log(diam)+1\)

    结合1、3得到答案为:\(\lceil \log(2*D)\rceil +1\).

  • 代码

    #include <bits/stdc++.h>
    #define ll long long
    #define fi first
    #define se second
    #define pb push_back
    #define me memset
    #define rep(a,b,c) for(int a=b;a<=c;++a)
    #define per(a,b,c) for(int a=b;a>=c;--a)
    const int N = 3e6 + 10;
    const int mod = 1e9 + 7;
    const int INF = 0x3f3f3f3f;
    using namespace std;
    typedef pair<int,int> PII;
    typedef pair<ll,ll> PLL;
    ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
    ll lcm(ll a,ll b) {return a/gcd(a,b)*b;}
     
    int n,m;
    vector<int> edge[N];
    bool vis[N];
    int dis[N];
     
    int main() {
    	scanf("%d %d",&n,&m);
    	me(dis,INF,sizeof(dis));
    	for(int i=1;i<=m;++i){
    		int u,v;
    		scanf("%d %d",&u,&v);
    		edge[u].pb(v);
    		edge[v].pb(u);
    	}
    	int mx=0;
    	queue<int> q;
    	dis[1]=0;
    	q.push(1);
    	while(!q.empty()){
    		int u=q.front();
    		q.pop();
    		if(vis[u]) continue;
    		vis[u]=true;
    		for(auto to:edge[u]){
    			if(dis[to]>dis[u]+1){
    				dis[to]=dis[u]+1;
    				q.push(to);
    				mx=max(mx,dis[to]);
    			}
    		}
    	}
    	for(int i=1;i<=n;++i){
    		if(dis[i]==INF){
    			puts("-1");
    			return 0;
    		}
    	}
    	printf("%d\n",(int)ceil(log2(mx))+1);
    	return 0;
    }
    

K. Unique Activities

二分答案,然后用hash来存字串判断即可

#include <bits/stdc++.h>
using namespace std;
#define PII pair<int,int>
#define fi first
#define se second
#define pb push_back
#define ll long long
#define ull unsigned long long
const int N=1e6+10;

int n;
string s;
ull base=196613;
ull h[N],p[N];


void init(){
    p[0]=1;
    for(int i=1;i<=n;++i){
        h[i]=h[i-1]*base+s[i]-'A';
        p[i]=p[i-1]*base;
    }
}

bool check(int x){
    unordered_map<ull,int> mp;
    for(int i=1;i<=n;++i){
        if(i>=x){
            mp[h[i]-h[i-x]*p[x]]++;
        } 
    }
    for(auto w:mp){
        if(w.se==1){
            return true;
        }
    }
    return false;
}

int main(){
    cin>>s;
    n=(int)s.size();
    s="`"+s;
    init();
    int l=1,r=n;
    while(l<r){
        int mid=(l+r)>>1;
        if(check(mid)) r=mid;
        else l=mid+1;
    }
    unordered_map<ull,int> mp;
    for(int i=1;i<=n;++i){
        if(i>=r){
            mp[h[i]-h[i-r]*p[r]]++;
        }
    }
    int ans=1;
    for(int i=1;i<=n;++i){
        if(i>=r && mp[h[i]-h[i-r]*p[r]]==1){
            ans=i;
            break;
        }
    }
    for(int i=ans-r+1;i<=ans;++i) cout<<s[i];
    return 0;
}

L. Restaurants

待补

???????????????????????????????????????????? ???????????????????????????????? ???????????? ???????????????? ???????????????? ???????????????????????????????? ???????? ????????????????