2019 ICPC Universidad Nacional de Colombia Programming Contest 题解

2019 ICPC Universidad Nacional de Colombia Programming Contest 题解

A:貌似是计算几何

#include<bits/stdc++.h>
using namespace std;
struct vec{
	int x,y;
	vec(int _x,int _y):x(_x),y(_y){
		int d=__gcd(x,y);
		x/=d,y/=d;
		if(x<0)x=-x,y=-y;
		if(x==0)y=abs(y);
	}
	bool operator==(vec b)const{
		return x==b.x&&y==b.y;
	}
	bool operator<(vec b)const{
		if(x!=b.x){
			return x<b.x;
		}
		return y<b.y;
	}
};
int main()
{
	int T;
	cin>>T;
	while(T--){
		int n;
		cin>>n;
		map<vec,int>cnt;
		long long ans=0;
		vector<pair<vec,int>>v;
		while(n--){
			int x1,x2,y1,y2;
			cin>>x1>>y1>>x2>>y2;
			vec t(x1-x2,y1-y2);
			v.push_back({t,t.x*y1-t.y*x1});
		}
		sort(v.begin(),v.end());
		v.erase(unique(v.begin(),v.end()),v.end());
		for(auto i:v){
			vec t=i.first;
			ans+=cnt[vec(-t.y,t.x)];
			cnt[t]++;
		}
		cout<<ans<<'\n';
	}
}

B:母鸡,队友写的

#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
 
const int N = 5e3 + 10;
string s;
 
int main()
{
    cin >> s;
    
    for (int len = 0; len <= s.length(); len++)
    {
        string tmp = s.substr(0, len);
        reverse(tmp.begin(), tmp.end());
        string check = s + tmp;
        string cur = check;
        reverse(cur.begin(), cur.end());
        if (check == cur)
        {
            cout << check << endl;
            return 0;
        }
    }
}

C:dp

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
const int INF=0x3f3f3f3f;
char s1[N],s2[N];
int dp[1005][1005];
int main(){
    scanf(" %s %s",s1+1,s2+1);
    int n=strlen(s1+1);
    int m=min(n,1000);
    int ans=0;
    for(int i=0;i<=m;i++)
        for(int j=0;j<=m;j++){
            int t1=0;
            if(i)t1=dp[i-1][j];
            while(t1+i+1<=n&&t1+j+1<=n&&s1[t1+i+1]==s2[t1+j+1])t1++;
            int t2=0;
            if(j)t2=dp[i][j-1];
            while(t2+i+1<=n&&t2+j+1<=n&&s1[t2+i+1]==s2[t2+j+1])t2++;
            dp[i][j]=max(t1,t2);
            ans=max(ans,dp[i][j]);
        }
    if(ans*100>=99*n)puts("Long lost brothers D:");
    else puts("Not brothers :(");
}

D:数据结构

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
const int INF=0x3f3f3f3f;
char s[N];
int fa[N][150];
struct node{
    int i,a,k;char c;
}q[N];
int _find(int x,int y){
    if(fa[x][y]==x)return x;
    else return fa[x][y]=_find(fa[x][y],y);
}
bool vis[N];
int main(){
    scanf(" %s",s+1);
    int n=strlen(s+1);
    int x=150;
    for(int i=1;i<=x;i++)
        for(int j=1;j<=n+1;j++)fa[j][i]=j;
    int m;scanf("%d",&m);
    for(int i=1;i<=m;i++)scanf("%d %d %d %c",&q[i].i,&q[i].a,&q[i].k,&q[i].c);
    for(int i=m;i>=1;i--){
        if(q[i].a>x){
            int k=q[i].k,c=q[i].c,p=q[i].i,a=q[i].a;
            for(int i=0;i<=k;i++){
                int be=p+i*a;
                if(!vis[be]){
                vis[be]=true;
                s[be]=c;
                for(int j=1;j<=x;j++)
                   fa[be][j]=min(_find(be,j)+j,n+1);
                }
            }
        }else{
            int k=q[i].k,c=q[i].c,p=q[i].i,a=q[i].a;
            for(int be=_find(p,a);be<=p+k*a;be=_find(be,a)){
                if(!vis[be]){
                vis[be]=true;
                s[be]=c;
                for(int j=1;j<=x;j++)
                    fa[be][j]=min(_find(be,j)+j,n+1);
                }
            }
        }
    }
    printf("%s\n",s+1);
}

E:扫描线

#include <bits/stdc++.h>
 
#define eps 1e-8
using namespace std;
const int N=1e5+10;
int maxx[N<<2],lazy[N<<2],n,d,len;
struct node{
    int pos,h;
    bool operator<(const node &a)const{
        return pos<a.pos;
    }
}q[N<<1];
void push_up(int rt){
    maxx[rt]=max(maxx[rt<<1],maxx[rt<<1|1]);
}
void push_down(int rt){
    if(lazy[rt]){
        lazy[rt<<1]+=lazy[rt];
        lazy[rt<<1|1]+=lazy[rt];
        maxx[rt<<1]+=lazy[rt];
        maxx[rt<<1|1]+=lazy[rt];
        lazy[rt]=0;
    }
}
void update(int l,int r,int L,int R,int val,int rt){
    if(L<=l&&r<=R){
        maxx[rt]+=val;lazy[rt]+=val;return ;
    }
    push_down(rt);int mid=(l+r)>>1;
    if(L<=mid)update(l,mid,L,R,val,rt<<1);
    if(mid<R)update(mid+1,r,L,R,val,rt<<1|1);
    push_up(rt);
}
int main()
{
    double x;scanf("%d %d %lf",&n,&d,&x);
    len=100*(x+eps);
    for(int i=1;i<=n;i++){
        scanf("%d %lf",&q[i].h,&x);q[i].pos=(x+eps)*100;
    }
    sort(q+1,q+n+1);
    for(int i=1;i<=n;i++)q[i+n]=q[i],q[i+n].pos+=36000;
    n<<=1;
    int nowp=1,ans=0;
    for(int i=1;i<=n;i++){
        int k=i;
        while(k<=n&&q[k].pos==q[i].pos){
            update(1,100000,max(q[k].h-d,1),q[k].h,1,1);k++;
        }
        i=k-1;
        while(q[nowp].pos+len<q[i].pos){
            update(1,100000,max(q[nowp].h-d,1),q[nowp].h,-1,1);nowp++;
        }
        ans=max(ans,maxx[1]);
    }
    printf("%d\n",ans);
    return 0;
}

F:强模

#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
 
const int N = 2e5 + 10;
string s;
ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
typedef pair<ll,ll> PII;
 
 
PII sub(PII p1, PII p2)
{
    ll a = p1.first, b = p1.second;
    ll c = p2.first, d = p2.second;
 
    ll fz = a * d - b * c;
    ll fm = b * d;
    ll g = gcd(abs(fz), abs(fm));
    fz /= g, fm /= g;
 
    return {fz, fm};
}
 
PII add(PII p1, PII p2)
{
    ll a = p1.first, b = p1.second;
    ll c = p2.first, d = p2.second;
 
    ll fz = a * d + b * c;
    ll fm = b * d;
    ll g =gcd(abs(fz), abs(fm));
    fz /= g, fm /= g;
 
    return {fz, fm};
}
 
int main()
{
    while (cin >> s)
    {
        stack<int>st;
        PII ans=make_pair(0,1);
        int op1=1,op2=1;
        for (int i = 0; i < s.length(); i++)
        {
            if (s[i] >= '0' && s[i] <= '9')
            {
                ll val1 = 0, val2 = 0;
                int j = i;
                while (s[j] != '/')
                {
                    val1 = val1 * 10 + s[j] - '0';
                    j++;
                }
                j++;
                while (s[j] >= '0' && s[j] <= '9')
                {
                    val2 = val2 * 10 + s[j] - '0';
                    j++;
                }
                PII t={val1,val2};
                if(op1*op2==1)ans=add(ans,t);
                else ans=sub(ans,t);
                i = j - 1;
            }
            else if (s[i] == '(') {
                op1=1;
                if(s[i-1]=='-'){
                        op2*=-1;st.push(-1);
                     }else st.push(1);
            }
            else if (s[i] == '+' || s[i] == '-')
            {
                op1=s[i]=='+'?1:-1;
            }
            else if (s[i] == ')')
            {
                op2*=st.top();st.pop();
            }
        }
        cout << ans.first << "/" << ans.second<< "\n";
    }
    return 0;
}

G:母鸡

#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
 
const int N = 1e4 + 10;
int n, k, a[N];
int deg[N], depth[N], fa[N];
vector<int>v[N];
 
void dfs(int val, int deep)
{
    depth[val] = deep;
    for (auto x: v[val]) dfs(x, deep + 1);
    return;
}
 
typedef pair<int,int> PII;
priority_queue<PII, vector<PII>, greater<PII> >qu;
 
int main()
{
    scanf("%d%d", &n, &k);
    for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
    
    for (int i = 1; i <= n; i++)
    {
        v[a[i]].push_back(i);
        fa[i] = a[i];
        deg[a[i]]++;
    }
    
    dfs(0, 0);
    
    for (int i = 1; i <= n; i++)
        if (!deg[i]) qu.push({-depth[i], i});
    
    int cnt = 0;
    while (!qu.empty())
    {
        cnt++;
        vector<int>cur;
        cur.clear();
        for (int i = 1; i <= k && !qu.empty(); i++)
        {
            int val = qu.top().second;
            qu.pop();
            cur.push_back(val);
        }
        
        for (auto x: cur)
        {
            deg[fa[x]]--;
            if (!deg[fa[x]] && fa[x] != 0)
            qu.push({-depth[fa[x]], fa[x]});
        }
    }
    printf("%d\n", cnt);
    
    return 0;
}

H:搜索

#include <bits/stdc++.h>
 
using namespace std;
typedef long long ll;
const ll mod=1e15+37;
const int N=5e6;
string s[3];
int cnt1,cnt2,now;
ll pow12[35];
ll a[N],b[N];
void dfs(int pos,int m,ll sum,int op,int n,ll a[]){
    if(pos==m){a[now++]=sum;return ;}
    for(int i=0;i<3;i++){
        ll sum1=(sum+s[i][pos]*pow12[n-pos-1]%mod)%mod;
        dfs(pos+1,m,sum1,op,n,a);
    }
}
ll solve(int n){
    a[0]=b[0]=0;
    now=0;
    dfs(0,n/2,0,0,n,a);
    cnt1=now;
    now=0;
    dfs(n/2,n,0,1,n,b);
    cnt2=now;
    sort(a,a+cnt1);
    sort(b,b+cnt2);
    ll ans=(a[0]+b[0])%mod;
    a[cnt1]=a[0]+mod,b[cnt2]=b[0]+mod;
    int pos=cnt2;
    for(int i=0;i<cnt1;i++){
        while(pos>0&&b[pos-1]+a[i]>=mod)pos--;
        ans=min(ans,(b[pos]+a[i])%mod)%mod;
    }
    return ans;
}
int main()
{
    pow12[0]=1;
    for(int i=1;i<30;i++)pow12[i]=pow12[i-1]*127%mod;
    int n,m;
    scanf("%d %d",&n,&m);
    for(int i=0;i<3;i++)cin>>s[i];
    ll ans1=solve(n);
    for(int i=0;i<3;i++)cin>>s[i];
    ll ans2=solve(m);
    if(ans1<ans2)puts("Owls");
    else if(ans1>ans2)puts("Goats");
    else puts("Tie");
    return 0;
}

I:不知道

#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
 
const int N = 2e5 + 10;
string s;
 
int main()
{
    cin >> s;
    int pos = -1;
    for (int i = 0; s[i]; i++)
    {
        if (s[i] >= '0' && s[i] <= '9') pos = i;
        else break;
    }
    if (pos == -1) cout << -1 << endl;
    else cout << s.substr(0, pos + 1);
    
    return 0;
}

J:线段树

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
const int INF=0x3f3f3f3f;
int n,m,a[N];
int len[N<<2];
ll sum[N<<2],lazy[N<<2],minx[N<<2];
void push_up(int rt){
    len[rt]=len[rt<<1]+len[rt<<1|1];
    sum[rt]=sum[rt<<1]+sum[rt<<1|1];
    minx[rt]=min(minx[rt<<1],minx[rt<<1|1]);
}
void push_down(int rt,int l,int r){
    if(lazy[rt]){
        int mid=(l+r)>>1;
        sum[rt<<1]-=len[rt<<1]*lazy[rt];
        minx[rt<<1]-=lazy[rt];
        lazy[rt<<1]+=lazy[rt];
        sum[rt<<1|1]-=len[rt<<1|1]*lazy[rt];
        minx[rt<<1|1]-=lazy[rt];
        lazy[rt<<1|1]+=lazy[rt];
        lazy[rt]=0;
    }
}
void build(int l,int r,int rt){
    if(l==r){sum[rt]=a[l];minx[rt]=a[l];len[rt]=1;return ;}
    int mid=(l+r)>>1;
    build(l,mid,rt<<1);
    build(mid+1,r,rt<<1|1);
    push_up(rt);
}
void update(int l,int r,int L,int R,int x,int rt){
    if(l==r){
        if(sum[rt]>x){
            sum[rt]-=x;
            minx[rt]-=x;
        }else {
            sum[rt]=0;
            minx[rt]=INF;
            len[rt]=0;
        }
        return ;
    }
    if(L<=l&&r<=R&&minx[rt]>=x){
        minx[rt]-=x;
        sum[rt]-=len[rt]*1ll*x;
        lazy[rt]+=x;return ;
    }
    push_down(rt,l,r);
    int mid=(l+r)>>1;
    if(L<=mid&&len[rt<<1]>0)update(l,mid,L,R,x,rt<<1);
    if(mid<R&&len[rt<<1|1]>0)update(mid+1,r,L,R,x,rt<<1|1);
    push_up(rt);
}
ll query(int l,int r,int L,int R,int rt){
    if(L<=l&&r<=R)return sum[rt];
    push_down(rt,l,r);
    ll sum=0;int mid=(l+r)>>1;
    if(L<=mid)sum+=query(l,mid,L,R,rt<<1);
    if(mid<R)sum+=query(mid+1,r,L,R,rt<<1|1);
    return sum;
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    build(1,n,1);
    while(m--){
        int op;scanf("%d",&op);
        if(op==1){
            int x,y;scanf("%d %d",&x,&y);
            if(x>y){
                ll sum1=query(1,n,x,n,1);
                ll sum2=query(1,n,1,y,1);
                printf("%lld\n",sum1+sum2);
            }else printf("%lld\n",query(1,n,x,y,1));
        }else {
            int x,y,z;scanf("%d %d %d",&x,&y,&z);
            if(x>y){
                update(1,n,x,n,z,1);
                update(1,n,1,y,z,1);
            }
            else update(1,n,x,y,z,1);
        }
    }
}

K:母鸡

#include<bits/stdc++.h>
using namespace std;
const int N=2e5;
char f[N+10];
int pre[N];
int main()
{
	f[1]=f[2]=1;
	for(int i=3;i<=N;i++){
		f[i]=f[i-1]+f[i-2];
		f[i]&=1;
	}
	pre[1]=0;
	for(int i=2;i<=N;i++){
		pre[i]=pre[i-1]+(f[i]^f[i-1]);
	}
	int T;
	cin>>T;
	while(T--){
		int n;
		cin>>n;
		if(n<=2){
			cout<<0<<'\n';
			continue;
		}
		cout<<pre[n]+1<<'\n';
	}
}

L:母鸡

#include <bits/stdc++.h>
using namespace std;
 
const int maxn = 1e6 + 5;
bool dp[maxn];
int pre[maxn], p[maxn];
 
int n, a[105], vis[105];
int cnt[maxn];
 
void check(int mid)
{
    int now = cnt[mid];
    memset(vis, 0, sizeof(vis));
    while (now) {
        vis[p[now - pre[now]]]++;
        now = pre[now];
    }
    printf("1\n");
    for (int i = 1; i <= n; i++)
        printf("%d ", vis[i]);
    printf("\n");
    fflush(stdout);
}
 
int main()
{
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
        scanf("%d", &a[i]);
 
    int limit = 1e6;
    dp[0] = true;
    for (int i = 1; i <= n; i++) {
        for (int j = 0; j <= limit - a[i]; j++)
            if (dp[j])
                dp[j + a[i]] = true,
                       pre[j + a[i]] = j;
    }
    int k = 0;
    for (int i = 1; i <= limit; i++)
        if (dp[i])
            cnt[++k] = i;
 
    for (int i = 1; i <= n; i++)
        p[a[i]] = i;
    char s[20];
    int left = 0, right = k, mid, ans = -1;
    int tl=0,tr=1e6;
    while (left <= right) {
        mid = (left + right) >> 1;
        check(mid);
        scanf("%s", s + 1);
        if (s[1] == 'y') {
            ans = cnt[mid];
            break;
        } else if (s[1] == 'g')
            left = mid + 1,tl=cnt[mid]+1;
        else
            right = mid - 1,tr=cnt[mid]-1;
    }
    if(tr==tl)ans=tl;
    printf("2\n%d\n", ans);
    fflush(stdout);
 
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值