这次只有 260260 /(ㄒoㄒ)/~~(本来应该有 360360 的 QAQ)

T1T1

解:按甜度和咸度分别降序排序,在计算最多吃几个,取最小值。

代码:

#include <bits/stdc++.h>
using namespace std;
const int N=2e5+50;
long long a[N],b[N];
bool cmp(long long a,long long b){
    return a>b;
}
int main(){
	freopen("eat.in","r",stdin);
    freopen("eat.out","w",stdout);
    long long n,x,y;
    cin >> n >> x >> y;
    for(long long i=1;i<=n;i++){
        cin >> a[i];
    }for(long long i=1;i<=n;i++){
        cin >> b[i];
    }
    sort(a+1,a+n+1,cmp);
    sort(b+1,b+n+1,cmp);
    long long as=0,bs=0,am=0,bm=0,flag=1;
    for(long long i=1;i<=n;i++){
        as+=a[i];
        if(as>x){am=i;flag=0;break;}
    }
    if(flag) am=n; 
    flag=1;
	for(long long i=1;i<=n;i++){
        bs+=b[i];
        if(bs>y){bm=i;flag=0;break;}
    }
    if(flag) bm=n;
    cout << min(am,bm);
}

T2T2

解:代码为打表后找规律版本,实际只需三重循环枚举即可(范围11~14{14}),代码应该很好理解,jh 函数表示在后面添加一个 1 , 即获取下一个纯 1 数。

代码:

#include <bits/stdc++.h>
#define int long long
using namespace std;
int jh(int x){
    return x*10+1;
}
signed main(){
    freopen("three.in","r",stdin);
    freopen("three.out","w",stdout);
    int n;
    cin >> n;
    int a=1,b=1,c=1;
    if(n==1){
    	cout << 3 << endl;
    	return 0;
	}
    for(int i=2;i<=n;i++){
        if(a==b&&b==c){
            c=jh(c);
            a=1;
            b=1;
        }else if(a==b&&b!=c){
            b=jh(b);
            a=1;
        }else if(a!=b){
            a=jh(a);
	    }
    }
    cout << a+b+c << endl;
}

T3T3

暴力骗了 6060

解:简单递推 DP

a[i][j] 表示首位是 i,末位是 j 的数字个数。

先枚举 AA(首位j末尾i),每次将答案加上 a[i][j]*2BB 在前面和后面算两组解),同时将 a[j][i] 增加 11

特判:由于存在个位数解,所以当 i=j 时额外增加一组解

代码:

#include <bits/stdc++.h>
#define int long long
using namespace std;
int a[11][11];
signed main(){
    freopen("number.in","r",stdin);
    freopen("number.out","w",stdout);
    int n;
    cin >> n;
    int ans=0;
    for(int i=1;i<=n;i++){
        int x=i%10,y=i;
        while(y/10>0) y/=10;
        if(x==y) ans++;
        ans+=a[x][y]*2;
        a[y][x]++;
    }
    cout << ans;
}

T4T4

解:首先,如果一个数有可能成为中位数,则比他小的数也可能成为。所以这题具有二段性,可以用二分(bs1),check函数比较难写,但其实也不难,我们可以用一个标记数组,把大于mid的标记为1,小的标记为0,在求一个二位前缀和,每次枚举所有矩阵,如果里面的1数量大于 k22\lfloor\frac{k^2}{2}\rfloor,则返回1,否则返回0,二分结果即为答案

代码:现在不能写了

T5T5

-1e18 写成了 -1 ,当时考试时间只剩几分钟了,我又手滑把自测点成了提交,导致本来能 ACAC 的代码直接爆 00 了(QAQ QAQ QAQ QAQ QAQ QAQ QAQ QAQ QAQ QAQ)

思路:模板题。

代码:

#include <bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int,int> PII;
signed main(){
    freopen("merge.in","r",stdin);
    freopen("merge.out","w",stdout);
    int n;
    cin >> n;
    vector<PII> a;
    for(int i=0;i<n;i++){
        int x,y;
        cin >> x >> y;
        a.push_back({x,y});
    }
    vector<PII> ans;
    sort(a.begin(),a.end());
    int l=-1e18,r=-1e18;
    for(auto it:a){
        if(r<it.first){ 
            if(l!=-1e18) cout << l << " " << r << endl;
            l=it.first,r=it.second;
        }
        else r=max(r,it.second);
    } 
    if(l!=-1) cout << l << " " << r << endl;
    return 0;
}

T6T6

解:先用并查集存储每个图,记得存储边数和点数,然后用无序集合存储每个图的根顶点。最后判断每个连通块是否有环(即边数=点数),如果都满足,则结果为 2cnt2^{cnt}cntcnt 为连通块的数量)

代码:

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+50,mod=998244353;
int fa[N],s1[N],s2[N];
void init(int n){
    for(int i=1;i<=n;i++){
        fa[i]=i;
        s1[i]=1;
        s2[i]=0;
    }
}
int find(int x){
	if(x==fa[x]) return x;
	else return fa[x]=find(fa[x]);
}
void merge(int a,int b){
    int x=find(a),y=find(b);
    if(x!=y){
        if(s1[x]<s1[y]) swap(x,y);
        fa[y]=x;
        s1[x]+=s1[y];
        s2[x]+=s2[y];
    }
}
int qmi(int a,int b){
    int res=1;
    while(b){
        if(b&1) res=res*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return res%mod;
}
signed main(){
    freopen("one.in","r",stdin);
    freopen("one.out","w",stdout);
    int n,m;
    cin >> n >> m;
    init(n);
    for(int i=1;i<=m;i++){
        int a,b;
        cin >> a >> b;
        s2[find(b)]++;
        merge(a,b);
    }
    unordered_set<int> rts;
    for(int i=1;i<=n;i++){
        rts.insert(find(i));
    }
    int cnt=0;
    for(auto rt:rts){
        if(s1[rt]==s2[rt]) cnt++;
        else{
            cout << 0;
            return 0;
        }
    }
    cout << qmi(2,cnt)%mod << endl;
}