冬日暖心赛 题解

差点翻车系列

A 断章取义

输出第L个到第R个字符串即可

#include <bits/stdc++.h>
/*
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
*/
using namespace std;

const double eps = 1e-10;
const double pi = 3.1415926535897932384626433832795;
const double eln = 2.718281828459045235360287471352;

#define f(i, a, b) for (int i = a; i <= b; i++)
#define scan(x) scanf("%d", &x)
#define mp make_pair
#define pb push_back
#define lowbit(x) (x&(-x))

#define fi first
#define se second
#define SZ(x) int((x).size())
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define summ(a) (accumulate(all(a), 0ll))

typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;

using ll=long long;

int n,l,r;
char s[(int)1e6+9];
int main()
{
    scanf("%d%d%d",&n,&l,&r);
    for(int i=1;i<=n;++i){
    	scanf("%s",s);
    	if(i>=l&&i<=r)printf("%s ",s);
    }
    return 0;
}

B 法术

算出圆交面积即可

#include <bits/stdc++.h>
/*
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
*/
using namespace std;

const double eps = 1e-10;
const double pi = 3.1415926535897932384626433832795;
const double eln = 2.718281828459045235360287471352;

#define f(i, a, b) for (int i = a; i <= b; i++)
#define scan(x) scanf("%d", &x)
#define mp make_pair
#define pb push_back
#define lowbit(x) (x&(-x))

#define fi first
#define se second
#define SZ(x) int((x).size())
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define summ(a) (accumulate(all(a), 0ll))

typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;

using ll=long long;

ll r,d; 
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>r>>d;
    if(d==0){
    	printf("%.7lf\n",pi*r*r*1.0);
    }
    if(d>=2*r){
    	printf("%.7lf\n",pi*r*r*2.0);
    }else{
		double ang=acos((r*r+d*d-r*r)/(2.0*r*d));
		double res=ang*r*r + ang*r*r - r*d*sin(ang);
    	printf("%.7lf\n",pi*r*r*2.0-res);
    }
    return 0;
}

C 错误的加法表

题目保证仅有唯一的修改方案,所以我们可以对每个位置进行检查,不符合条件先检查行列,行列都正常那么改变该元素值即可。

#include <bits/stdc++.h>
/*
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
*/
using namespace std;

const double eps = 1e-10;
const double pi = 3.1415926535897932384626433832795;
const double eln = 2.718281828459045235360287471352;

#define f(i, a, b) for (int i = a; i <= b; i++)
#define scan(x) scanf("%d", &x)
#define mp make_pair
#define pb push_back
#define lowbit(x) (x&(-x))

#define fi first
#define se second
#define SZ(x) int((x).size())
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define summ(a) (accumulate(all(a), 0ll))

typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;

using ll=long long;

ll n,m;
ll a[1009][1009]; 

bool check(int t,int sta,int x,int y){
	if(sta&1){
		for(int i=2;i<=m;++i){
			if(i==y)continue;
			if(a[t][1]+a[1][i]!=a[t][i])return true;
		}
	}else{
		for(int i=2;i<=n;++i){
			if(i==x)continue;
			if(a[1][t]+a[i][1]!=a[i][t])return true;
		}
	}
	return false;
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n>>m;
    f(i,1,n)f(j,1,m)cin>>a[i][j];
    if(a[1][1]!=0){
    	cout<<"1 1 0";
    	return 0;
    }
    for(int i=2;i<=n;++i){
    	for(int j=2;j<=m;++j){
    		if(a[i][1]+a[1][j]!=a[i][j]){
    			if(check(i,1,i,j)){
    				printf("%d %d %lld",i,1,a[i][j]-a[1][j]);
    			}else if(check(j,0,i,j)){
    				printf("%d %d %lld",1,j,a[i][j]-a[i][1]);
    			}else printf("%d %d %lld",i,j,a[i][1]+a[1][j]);
    			return 0;
    		}
    	}
    }
    return 0;
}

D 外号

差点翻车,考虑冲突仅存在于两个字符串相同或者其中一个是另一个字符串的子串。所以我们可以先对字符串进行排序,然后两个相邻的进行检查即可。

#include <bits/stdc++.h>
/*
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
*/
using namespace std;

const double eps = 1e-10;
const double pi = 3.1415926535897932384626433832795;
const double eln = 2.718281828459045235360287471352;

#define f(i, a, b) for (int i = a; i <= b; i++)
#define scan(x) scanf("%d", &x)
#define mp make_pair
#define pb push_back
#define lowbit(x) (x&(-x))

#define fi first
#define se second
#define SZ(x) int((x).size())
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define summ(a) (accumulate(all(a), 0ll))

typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;

using ll=long long;

ll n;
bitset<(int)1e5+9> vis;
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n;
    vector<pair<string,int>> v(n);
    f(i,1,n)cin>>v[i-1].first,v[i-1].second=i;
    sort(all(v));
    for(int i=1;i<v.size();++i){
        auto [aa,bb]=v[i-1];
        auto [cc,dd]=v[i];
        if(aa==cc)vis[bb]=vis[dd]=1;
        else if(aa.size()<cc.size()){
            auto it=string(cc.begin(),cc.begin()+(int)aa.size());
            if(it==aa)vis[bb]=1;
        }
    }
    f(i,1,n)cout<<(vis[i]?"No\n":"Yes\n");
    return 0;
}

E 卖瓜

按题意就是要个数据结构维护动态区间最小值,然后一个对位置的询问可以用map套set二分查找即可。

#include <bits/stdc++.h>
/*
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
*/
using namespace std;

const double eps = 1e-10;
const double pi = 3.1415926535897932384626433832795;
const double eln = 2.718281828459045235360287471352;

#define f(i, a, b) for (int i = a; i <= b; i++)
#define scan(x) scanf("%d", &x)
#define mp make_pair
#define pb push_back
#define lowbit(x) (x&(-x))

#define fi first
#define se second
#define SZ(x) int((x).size())
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define summ(a) (accumulate(all(a), 0ll))

typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;

using ll=long long;
using LL =long long;

const int maxm=1e5+9;
template <class T> inline T read(const T sample) {
    T x=0; int f=1; char s;
    while((s=getchar())>'9'||s<'0') if(s=='-') f=-1;
    while(s>='0'&&s<='9') x=(x<<1)+(x<<3)+(s^48),s=getchar();
    return x*f;
}
template <class T> inline void write(const T x) {
    if(x<0) return (void) (putchar('-'),write(-x));
    if(x>9) write(x/10);
    putchar(x%10^48);
}
ll aa[(int)2e5+9],n,m;
struct BIT
{
    LL  h[(int)1e5 + 9], n;
    void init(int x)
    {
        n = x;
        f(i,1,n)update(i);
    }
    void update(int x)
    {
        while(x<=n){
            h[x]=aa[x];
            int low=lowbit(x);
            for(int i=1;i<low;i<<=1)h[x]=min(h[x],h[x-i]);
            x+=lowbit(x);
        }  
    }
    LL gmin(int l, int r)
    {
        LL ans = 1e18;
        while (r >= l)
        {
            ans = min(ans, aa[r]);
            r--;
            while (r - lowbit(r) >= l)
            {
                ans = min(h[r], ans);
                r -= lowbit(r);
            }
        }
        return ans;
    }
}b;


map<int,set<int>> cov;

int main()
{
    n=read(1),m=read(1);
    for(int i=1;i<=n;++i)aa[i]=read(1),cov[aa[i]].insert(i);
    b.init(n);

    for(int i=1,x,y,z;i<=m;++i){
        x=read(1),y=read(1),z=read(1);
        int abc=b.gmin(x,y);
        auto it=cov[abc].lower_bound(x);
        write(*it),putchar(' ');
        aa[*it]=z;
        b.update(*it);
        cov[aa[*it]].insert(*it);
        cov[abc].erase(it);
    }
    return 0;
}

F 分糖果

看样例可以发现,先填满$p\times q$矩阵,然后复制粘贴成$n\times m$矩阵输出即可。

#include <bits/stdc++.h>
/*
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
*/
using namespace std;

const double eps = 1e-10;
const double pi = 3.1415926535897932384626433832795;
const double eln = 2.718281828459045235360287471352;

#define f(i, a, b) for (int i = a; i <= b; i++)
#define scan(x) scanf("%d", &x)
#define mp make_pair
#define pb push_back
#define lowbit(x) (x&(-x))

#define fi first
#define se second
#define SZ(x) int((x).size())
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define summ(a) (accumulate(all(a), 0ll))

typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;

using ll=long long;

ll n,m,p,q,k,a[1009][1009];
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>n>>m>>p>>q>>k;
    for(int i=1,st=0;i<=p&&st<k;++i)for(int j=1;j<=q&&st<k;++j){
        a[i][j]=1,st+=1;
    }
    for(int i=1;i<=n;++i){
        for(int j=1;j<=m;++j){
            printf("%lld%c",a[(i-1)%p+1][(j-1)%q+1]," \n"[j==m]);
        }
    }
    return 0;
}

G 永眠镇

洛谷 P3478 [POI2008] STA-Station 原题,懒得码照抄?

#include<cstdio>
using namespace std;
const int N=1e6+10;
struct Edge{
    int to,nxt;
}e[N<<1];
int dep[N],hd[N],tot;
void add(int u,int v){
    e[++tot]={v,hd[u]},hd[u]=tot;
    e[++tot]={u,hd[v]},hd[v]=tot;
}
int siz[N];
long long dp[N];
void dfs(int u,int fa){
    siz[u]=1;dp[u]=dep[u];
    for(int i=hd[u];i;i=e[i].nxt){
        int v=e[i].to;
        if(v==fa)continue;
        dep[v]=dep[u]+1;
        dfs(v,u);
        siz[u]+=siz[v];
        dp[u]+=dp[v];
    }
}    
int n;
void calc(int u,int fa){
    for(int eg=hd[u];eg;eg=e[eg].nxt){
        int v=e[eg].to;
        if(v==fa)continue;
        dp[v]=dp[u]-siz[v]+n-siz[v];
        calc(v,u);
    }
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<n;i++){
        int a,b;
        scanf("%d%d",&a,&b);
        add(a,b);
    }
    dfs(1,0);
    calc(1,0);
    int ans=0;
    for(int i=1;i<=n;i++)
        if(dp[ans]<dp[i])ans=i;
    printf("%d\n",ans);
}

H 不同的GCD

考虑一个二进制下的含义,如何定义一个运算使得$f(a_i)=f(a_j)\iff a_i=a_j$。

对于异或运算,只能保证相同位置上不同值的情况下满足,那么要接下来要解决的就是相同的情况下的问题。

不妨设相同就保留原值,不同就为0,但我们用两倍长度来记录,前者是取反,后者是原值。

例如:$(10)_2$和$(00)_2$,那么在与$(00)_2$运算就会得到$0100$和$1100$可以发现对应位置$0 – 0$说明该位置和运算数不同,$1 – 0$代表该位置应该是1,$0 – 1$相应的就是0了。

#include <bits/stdc++.h>
/*
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
*/
using namespace std;

const double eps = 1e-10;
const double pi = 3.1415926535897932384626433832795;
const double eln = 2.718281828459045235360287471352;

#define f(i, a, b) for (int i = a; i <= b; i++)
#define scan(x) scanf("%d", &x)
#define mp make_pair
#define pb push_back
#define lowbit(x) (x&(-x))

#define fi first
#define se second
#define SZ(x) int((x).size())
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define summ(a) (accumulate(all(a), 0ll))

typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef vector<int> vi;

using ll=long long;

ll pr[(int)1e6+9],tot,n,ans[(int)1e6+9],k=0,lim=1;
bitset<(int)1e6+9> vis;

ll gcd(ll ma,ll mi){return mi?gcd(mi,ma%mi):ma;}

void init(){
	for(ll i=2;i<=1e6;++i){
		if(!vis[i]){
			pr[++tot]=i;
			for(ll j=1;i*j<=1e6;++j)vis[i*j]=1;
		}
	}
}
 
bool check(int x){
	if(ans[x]>1e18||ans[x]<0)return true;
	map<ll,int> cnt;
	for(int i=1;i<=n;++i){
		ll gc=gcd(ans[i],ans[x]);
		if(cnt[gc]==1)return true;
		cnt[gc]+=1;
	}
	return false;
}

void solve(){
	cin>>n;
	if(n==1){
    	cout<<"1\n";
    	return ;
    }
    lim=1,k=0;
    while(lim<n)lim<<=1,k+=1;
    for(int i=0;i<(1ll<<k);++i)ans[i]=1;
    ll gd=(1ll<<k)-1;
    for(int i=0;i<(1ll<<k);++i){
    	for(int j=0;j<k;++j)if((i>>j)&1)ans[i]=ans[i]==0?pr[j+1]:ans[i]*pr[j+1];
    }
	for(int i=0;i<(1ll<<k);++i){
    	for(int j=0;j<k;++j)if((i>>j)&1)ans[(~i)&gd]=ans[(~i)&gd]==0?pr[j+1+k]:ans[(~i)&gd]*pr[j+1+k];
    }
	f(i,0,n-1)cout<<ans[i]<<" \n"[i==n-1];
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    init();

    solve();
    
    return 0;
}
上一篇
下一篇