2024杭电2

1010.女神的睿智

题意:
8个字符,按顺序合成为4个,再合成为两个,在合成为一个,问最后颜色。

题解:
签到题,比较一下第1个字符和第4个字符就行了.

代码:

#include<bits/stdc++.h>
using namespace std;
typedef __int128 i128;
typedef long long ll;
typedef double db;

const db PI = acos(-1);
typedef array<ll, 2> PII; // vector<PII> a(n+1);
const ll inf = 2e18 + 10;
const int mod = 998244353;
const int MAX = 2e5 + 10;
bool multi = 1;

void Solve() {
    string s; cin >> s;
    ll cnt1 = 0, cnt2 = 0;
    for(ll i = 0; i <= 7; i ++ ) {
        if(s[i] == s[0]) cnt1 ++ ;
        else if(s[i] == s[4]) cnt2 ++ ;
    }
    if(s[0] == s[4]) {
        cout << s[0] << "\n";
    } else if(cnt1 != cnt2) {
        if(cnt1 > cnt2) cout << s[0] << "\n";
        else cout << s[4] << "\n";
    } else {
        cout << "N" << "\n";
    }
}


signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    ll T = 1;
    if(multi) cin >> T;
    while(T -- ) {
        Solve();
    }
    return 0;
}

1006.传奇勇士小凯


题意:
有一颗n节点的树,每个节点有一个怪兽,消灭节点 i i i的怪兽的概率是 p i 15 \frac{p_i}{15} 15pi。无论消灭成功都要停留一天,消灭了当前节点的怪兽可以移动到子节点。消灭完叶子节点怪兽后结束。
树根节点为 1 1 1,从根节点开始,到结束时,停留天数的最大期望。

题解:
就是几何分布。成功概率为p ,失败概率是1-p。失败次数m的数学期望 E(m) =(1-p)/p。
所以每个节点停留时间就是(1-p)/p。再求到每个叶子节点的期望最大值。

代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+6;

vector<int>a[N];
int p[N];
int fz,fm,xx,yy;
int y[N],x[N];

void cmp(int z,int m)
{
	int aa,bb;
	if(!fz){
		fz=z;
		fm=m;
		return ;
	}
	int g=__gcd(fm,m);
	int c=m*fm/g;
	aa=c/fm*fz;
	bb=c/m*z;
	if(bb>aa){
		fz=z;
		fm=m;
	}
}
void sum(int z,int m,int zz,int mm)
{
	int g=__gcd(m,mm);
	int c=m*mm/g;
	xx=c/m*z+c/mm*zz;
	yy=c;
}
void dfs(int u,int fa,int z,int m)
{
	cmp(z,m);
	for(auto i:a[u]){
		if(i==fa)continue;
		sum(z,m,x[i],y[i]);
		dfs(i,u,xx+yy,yy);
	}
}

void solve()
{
	fz=0, fm=0;
	int n,u,v;
	cin>>n;
	for(int i=1;i<n;i++){
		cin>>u>>v;
		a[u].push_back(v);
		a[v].push_back(u);
	}
	for(int i=1; i<=n; i++){
		cin>>p[i];
		y[i]=p[i];
		x[i]=15-p[i];
	}
	dfs(1,0,x[1]+y[1],y[1]);
	for(int i=1; i<=n ;i++)a[i].clear();
	
	int g=__gcd(fz,fm);
	fz/=g;
	fm/=g;
	

	cout<<fz<<'/'<<fm<<'\n';
	
}

signed main()
{
    int T=1;
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
    cin >> T;
    while (T--) {
        solve();
    }
    return 0;
}

1007.URL划分

题意:
一个字符串URL,输出 所使用的传输协议,网络位置,以及其在路径字符串子结构中定义的环境变量。

题解:
根据题目规则,自取字符串就可以了

代码:

#include <bits/stdc++.h>
#define int long long
using ll = long long;
using PII = std::array<int, 2>;
using namespace std;
const ll INF = 2E18 + 10;
#ifdef __clang__
    template <typename T>
    inline int my_lg(T n) {
        return (n > 0) ? static_cast<int>(log2(n)) : -1;
    }
    #define __lg my_lg
    #define __gcd gcd
#endif
#ifndef ONLINE_JUDGE
    #include "_debug.h"
#endif
// struct cmp{bool operator()(const int & x, const int &y) const{ return x<y;}};
const int N = 2E6 + 10;

void SINGLE_TEST() 
{
    string s;cin>>s;
    string t;
    int cnt=0;
    bool d=0;
    for(int i=0;i<s.size();i++){
        if(s[i]==':' || s[i]=='/'){
            cnt++;
            if(cnt<=4){
                cout<<t;
                if(cnt==1||cnt==4){
                    cout<<"\n";
                }
            }else{
                if(d){
                    cout<<t<<"\n";
                }
            }
            t.clear();
            d=0;
        }else{
            t+=s[i];
            if(s[i]=='=') d=1;
        }
    }
}

signed main() {
    cin.tie(nullptr)->sync_with_stdio(false);

    int SAMPLES = 1;
    cin >> SAMPLES;
    while (SAMPLES--) SINGLE_TEST();
}

1001.鸡爪


题意:
一个鸡爪是由 4 4 4个部分组成,一个点与三个与该点相邻的边,三个边的另一端点被认为不在鸡爪中。
给定边点数量 n n n,构造最多鸡爪数量的图。输出字典序最小的可能。

题解:
首先可以有 n 3 \frac{ n}{3} 3n个鸡爪,为了让字典序最小,就是前 n 3 \frac{ n}{3} 3n个节点是鸡爪中心。鸡爪的3条边尽量往小的连,不能有重边。就跳到 n 3 \frac{ n}{3} 3n后就行了。

代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+6;
vector<int>a[N];
pair<int,int>s[N];
int q,d[N];
void solve()
{
	int n,p,y;
	q=1;
	cin>>n;
	int x=n/3,m=n,ma=1;
	for(int i=1;i<=20000;i++){
		a[i].clear();	
		d[i]=0;
	}
	for(int i=1;i<=x;i++){
		p=3,y=1;
		while(p--){
			if(y==i)y=x+1;
			int u=min(i,y),v=max(i,y);
			s[q++]={u,v};
			m--;
			ma=max(ma,y);	
			y++;
		
		}
	}
	ma++;
	while(m--){
		s[q++]={1,ma};	
		ma++;
	
	}
//	dfs(1,0);
	sort(s+1,s+n+1);
	for(int i=1;i<=n;i++){
		cout<<s[i].first<<' '<<s[i].second<<'\n';
	}
	
}

signed main()
{
	int T=1;
	cin>>T;
	while(T--){
		solve();
	}
}

1011.在 A 里面找有 C 的 B

题意:
有字符串A,C。n个字符串 b 1 b1 b1, b 2 b2 b2
n次询问,如果 b 1 i b1_i b1i在A中,C在 b 2 i b2_i b2i中。

题解:
首先,C在 b 2 i b2_i b2i中,每次遍历 b 2 b2 b2字符串,看有没有C就行了,主要问题是 b 1 i b1_i b1i在A中。多出询问,不能每一次都遍历字符串A。
用到后缀数组算法。可以很快的在字符串S 中找 字符串T ,字符串S 的长度为 n,字符串T 的长度为 m,则复杂度为 O(m log n )
模板就能解决了

代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5 + 6;

string S, pp, c, q;
int sa[N], rk[N], tmp[N];
int k;

bool cmp(int a, int b) {
    if (rk[a] != rk[b]) {
        return rk[a] < rk[b];
    }
    int ra = (a + k <= S.length()) ? rk[a + k] : -1;
    int rb = (b + k <= S.length()) ? rk[b + k] : -1;
    return ra < rb;
}

void construct_sa() {
    int n = S.length();
    for (int i = 0; i <= n; i++) {
        sa[i] = i;
        rk[i] = (i < n) ? S[i] : -1;
    }
    for (k = 1; k <= n; k *= 2) {
        sort(sa, sa + n + 1, cmp);
        tmp[sa[0]] = 0;
        for (int i = 1; i <= n; i++) {
            tmp[sa[i]] = tmp[sa[i - 1]] + (cmp(sa[i - 1], sa[i]) ? 1 : 0);
        }
        for (int i = 0; i <= n; i++) {
            rk[i] = tmp[i];
        }
    }
}

bool contain(const string &T) {
    int l = 0, r = S.length();
    while (l <= r) {
        int mid = (l + r) / 2;
        int cmp_result = S.compare(sa[mid], T.length(), T);
        if (cmp_result == 0) {
            return true;
        } else if (cmp_result < 0) {
            l = mid + 1;
        } else {
            r = mid - 1;
        }
    }
    return false;
}

void solve() {
    int n;
    cin >> n;
    cin >> S >> pp;
    construct_sa();
    int f = 0;
    for (int i = 1; i <= n; i++) {
        cin >> c >> q;
        if (contain(c) && q.find(pp) != string::npos) {
            if (f) cout << ' ';
            cout << i;
            f = 1;
        }
    }
    cout << '\n';
}

signed main() {
    cin.tie(nullptr)->sync_with_stdio(false);
    int T;
    cin >> T;
    while (T--) {
        solve();
    }
    return 0;
}

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值