首页 > 其他分享 >题解9.29-10.3

题解9.29-10.3

时间:2024-10-03 16:33:09浏览次数:1  
标签:10.3 int 题解 9.29 cin long while res using

1.MakeitAlternating
如果它已经是交替的序列我们就不用管了,最终的目的是把序列变成交替的序列,那么我们可以把连续相同的数
全部取出来只留下一个,可以分成几段相同的数,最后的结果就是把这些相同的数全部只保留一个,用排列组合C(m,1);
第一个结果很简单,把重复的数加一下即可,后面的答案我们用C(m,1)算出来每个的数量,最后把拿出来的数全排列一下就行。

#include <bits/stdc++.h>

using namespace std;
#define int long long int


int MOD =998244353;

int res[2000001];
//预处理把所有的阶乘算出来
void init()
{
    res[0] = 1;
    for (int i = 1; i <= 200000; i++)
    {
        res[i] = res[i - 1] * i % MOD;
        // cout << res[i] << ' ';
    }
}


int32_t main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    init();
    int t;
    cin>>t;
    while(t--){
        string s;
        cin>>s;
        int cs=0;
        int ans=1;
        int q=1;

        char cnt=s[0];
        for (int i =1; i < s.length(); ++i) {
            if(s[i]==cnt)cs++,q++;
            else{
                cnt=s[i];
                if(q!=1)
                ans*=q;
                ans%=MOD;
                q=1;
            }
        }
        if(q!=1){
            ans*=q;
            ans%=MOD;
            q=1;
        }
        if(ans==1) cout<<cs<<' '<<1<<'\n';
        else
        cout<<cs<<" "<<(res[cs]*ans)%MOD<<'\n';
    }
    return 0 ;
}

2. 2.C. Black Circles
两点之间直线最短,如果刚好相切,可以画图证明一下也是可以的,这里注意不要用sqrt精度不行,所以直接用乘积比较

#include <bits/stdc++.h>
using namespace std;
#define int long long
struct node{
    int x;
    int y;
}v[100001];
int32_t main(){
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    int t;
    cin>>t;
    while(t--){
        int n;
        cin>>n;
        for (int i = 1; i <=n ; ++i) {
            cin>>v[i].x>>v[i].y;

        }
        int tx,ty;
        int ex,ey;
        cin>>tx>>ty;

        cin>>ex>>ey;
        int pd=0;
        int dis=((tx - ex) * (tx - ex) + (ty - ey) * (ty - ey));
        for (int i = 1; i <=n; ++i) {
            int dis1=((v[i].x - ex) * (v[i].x - ex) + (v[i].y - ey) * (v[i].y - ey));
            if(dis1<=dis){
                pd=1;
                break;
            }
        }
        if(pd)cout<<"NO\n";
        else cout<<"YES\n";
 }

}

3.The Strict Teacher (Hard Version))
二分,给出的数是有顺序的,目的是找最接近的左边和右边的数,两边二分即可

#include <bits/stdc++.h>
using  namespace  std;

#define  int long long

int32_t main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int t;
    cin>>t;
    while(t--){
        int n,m,q;
        cin>>n>>m>>q;
        set<int>st;
        set<int,greater<>>st2;
        st.insert(0);
        st2.insert(0);
        for (int i = 1; i <=m ; ++i) {
              int b;
              cin>>b;
              st.insert(b);
              st2.insert(b);
        }
        while(q--){
            int d;
            cin>>d;
            int f=*st.upper_bound(d);
            int h=*st2.upper_bound(d);
            if(f<=d){
                cout<<n-h<<'\n';
            }else if(h==0){
                cout<<f-1<<'\n';
            }else{
                cout<<(f-h)/2<<'\n';
            }
           // cout<<"f: "<<f<<" h: "<<h<<'\n';

        }
    }
}

4.F.Sakurako'sBo
考察题目逆元的性质,计算除法的时候会改变值,这个时候我们用快速幂逆元写即可

#include <bits/stdc++.h>
using  namespace  std;

#define  int long long


int MOD=1000000007;
int f[1008611];
int pre[1008611];
int qpow(int a,int n)
{
    int res=1;
    while(n){
        if(n&1) res=res*a%MOD;
        n>>=1;
        a=a*a%MOD;
    }
    return res;
}

int32_t main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int t;
    cin>>t;
    while(t--){
        int n;
        cin>>n;
        pre[0]=0;
        for (int i = 1; i <=n ; ++i) {
            cin>>f[i];
            pre[i]=pre[i-1]+f[i];
        }
        int sum=0;
        for (int i = 1; i <n ; ++i) {
            sum+=((f[i]%MOD*((pre[n]-pre[i])%MOD)%MOD))%MOD;
            sum%=MOD;
        }
        int fm=(n*(n-1)/2)%MOD;//这也要记得mod
        cout<<(sum%MOD* qpow(fm,MOD-2))%MOD<<'\n';
    }
}

5.C. Absolute Zero
找规律发现,以最大的数依次除二与数组进行取绝对值,最后会变成1或者是0,我一开始直接拿最大的数操作,但是wa了二,很明显
最大的数有可能进行40次操作不一定够,于是想到数据的范围不超过2的30次方,那么我们把最大的数设置为2的29次方,拿最终经过30或者31次操作必有解

#include <bits/stdc++.h>
using  namespace  std;

#define  int long long


int MOD=1000000007;
int f[1008611];
int qpow(int a,int n)
{
    int res=1;
    while(n){
        if(n&1) res=res*a;
        n>>=1;
        a=a*a;
    }
    return res;
}

int32_t main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int t;
    cin>>t;
    while(t--){
        int n;
        cin>>n;
        int maxx=0;
        int maxd=0;
        int ji=0;
        int ou=0;
        for (int i = 1; i <=n ; ++i) {
            cin>>f[i];
            if(f[i]%2==0)ou=1;
            else ji=1;
            maxd=max(maxd,f[i]);
        }
        int pd=0;

        if(maxd==0){
            cout<<0<<'\n';
            cout<<'\n';
            continue;
        }
        if(ji&&ou)pd=1;
        maxx= qpow(2,29);
        if(pd){
            cout<<-1<<'\n';
        }else{
            int ans=0;
            int res=maxx;
            int d=abs(f[n]-1);
            while(maxx>0){
              //  cout<<maxx<<' ';
                d=abs(d-maxx);
                maxx/=2;
                ans++;
                if(ans>40){
                    pd=1;
                    break;
                }
            }
            if(pd){
                cout<<-1<<'\n';
                continue;
            }if(ans!=0&&d==0)
            cout<<ans+1<<'\n';
            else if(ans!=0&&d==1){
                cout<<ans+2<<'\n';
            }
            else
                cout<<ans<<'\n';
            while(res>0){
                cout<<res<<' ';
                res/=2;
                ans++;

            }
            if(ans!=0)
            cout<<1<<' ';
            if(ans!=0&&d==1)
                cout<<1<<' ';
            cout<<'\n';
        }
    }
}

6.B. Battle Cows
题单上写的二分,我一直往二分方向考虑,想不出来,后面看题解发现根本不是二分的思路,我们如果要比赛赢的
最多,我们必须比前面的都大,这个时候我们跟第一个数交换,如果前面出现比自己的数大,那么我们就跟从第一个
开始比自己大的数交换,然后比较这两个数谁大就行

#include <bits/stdc++.h>
using namespace std;

int a[1008611];
void solve()
{
    int n,k,i; cin>>n>>k;
    for(i=1;i<=n;i++) cin>>a[i];
    swap(a[k],a[1]);
    int ans1=0;  //与第一个人交换的方案的胜场数
    for(i=2;i<=n;i++)
    {
        if(a[i]>a[1]) break;
        else ans1++;
    }
    swap(a[k],a[1]); //swap回来进行下一个方案的求解

    int flag=n+1,ans2=0; //flag为第一个比k大的人的下标
    for(i=1;i<=n;i++)
        if(a[i]>a[k])
        {
            flag=i;
            break;
        }
    if(flag<k)
    {
        swap(a[k],a[flag]);
        if(flag>1) ans2++;//特判当前k是不是在开头,否则会赢前面的人一场
        for(i=flag+1;i<=n;i++)
        {
            if(a[i]>a[flag]) break;
            else ans2++;
        }
    }
    cout<<max(ans1,ans2)<<"\n";
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int t;
    cin>>t;
    while (t--){
        solve();
    }
}

7.1.E. Secret Box
不难,但是思路错了,我的想法是它要凑出x,y,z的数量,并且x,y,z的点必须是相联的,
然后我去计算点数的时候也出错了,就一直想不通,其实大体思路没错,但是没有想清楚,每个点
从1开始向后移动就是连续的了,我们只需要枚举x,y,用k/x*y,去找c即可,最主要的原因还是没有分析
清楚,找不出计算的规律

#include <iostream>
using namespace std;
using ll = long long;

int main(){
	int t; cin >> t;
	while(t--){
		ll x, y, z, k; cin >> x >> y >> z >> k;
		ll ans = 0;
		for(int a = 1; a <= x; a++){
			for(int b = 1; b <= y; b++){
				if(k % (a * b)) continue;
				ll c = k / (a * b);
				if(c > z) continue;
				ll ways = (ll)(x - a + 1) * (y - b + 1) * (z - c + 1);
				ans = max(ans, ways);
			}
		}
		cout << ans << "\n";
	}
}

标签:10.3,int,题解,9.29,cin,long,while,res,using
From: https://www.cnblogs.com/dontian/p/18445755

相关文章

  • CF1051F题解
    传送门:https://codeforces.com/problemset/problem/1051/F注意到\(m-n\le20\),求一个连通图中任意两点间最短路,我们不难想到将问题转换到树上。先求出树的任意一颗生成树,此时倍增或者树刨能轻松算出仅含树边的最小路径。而对于非树边,从边的角度显然很难做到,我们不妨从点的角度思......
  • 10.3数据结构
    二叉树表示与储存:parlchrch二叉树遍历:前序,中序,后序遍历先序遍历先根、左子树、右子树中序遍历左子树、根、右子树后序遍历左子树、右子树、根无根树的遍历......
  • 题解:CF724E Goods transportation
    可以在cnblog中阅读。题意有\(n\)座城市,第\(i\)座城市生产了\(p_i\)件货物,最多可以出售\(s_i\)件货物,编号小的城市可以向编号大的城市运输至多\(c\)件货物,问最多能出售多少货物。\(n\le10^4\)。分析乍一看是一个网络流问题,可以这样建图,令\(S\)为源点\(T\)......
  • ABC221G Jumping Sequences 题解
    JumpingSequences把移动的上下左右改成左上、左下、右上、右下(坐标轴旋转\(45\)°)。则最终目的地是\((A+B,A-B)\)。(以前移动的方式是\((\pmd_i,0),(0,\pmd_i)\)。现在每次移动的方式是\((\pmd_i,\pmd_i)\))则\(x,y\)两维可以分开考虑。目标:从\(d_1\simd_n\)中选......
  • Codeforces Round 976 (Div. 2) 题解
    CodeforcesRound976(Div.2)题解2020B一个常见的想法:开关灯=异或,虽然在这道题里没啥用注意到,第i盏灯的按钮被按的次数就是i的除它本身以外的因子个数而完全平方数的因子数为奇数,其他数的因子数为偶数点击查看更多信息#include<bits/stdc++.h>usingnamespacestd;voi......
  • 题解:CF1976D Invertible Bracket Sequences
    可以在cnblog中阅读。题意给一个合法括号序列,问有多少区间\([l,r]\),使得将区间内的每个括号翻转后,括号序列仍合法。分析十分套路地,我们将(看成\(+1\),将)看成\(-1\),则一个括号序列合法的充要条件是转换后的序列满足:前缀和任意位置非负;最后一项为\(0\)。考虑翻转......
  • ZZJC新生训练赛第二场题解
    先给出比赛链接:https://ac.nowcoder.com/acm/contest/92036A小红打怪ShowCodeAclassPoint{//点类public:intx,y;Point(){}Point(intx,inty):x(x),y(y){}Pointoperator+(constPoint&P)const{returnPoint(x+P.x,y+P.y);......
  • 题解:TopCoder12316 ThreeColorability
    Vjudge可以出成《三色绘恋》背景。题意给一个格点数为\((n+1)\times(m+1)\)的网格,给格点染色,相邻的格点不能染成同样的颜色。每个格子有一条对角线的边,可选N形和Z形。现在有一个残缺的网格,存在一些格子的对角线连法不确定,构造一种字典序最小的方案使得至少存在一种染色......
  • 树上最值路径 题解
    题意简述给你一棵\(n\)个结点的树,编号为\(1\simn\),求有多少路径\(\operatorname{Path}(u\rightarrowv)\),满足\(u=\max\{x\midx\in\operatorname{Path}(u\rightarrowv)\}\),\(v=\min\{x\midx\in\operatorname{Path}(u\rightarrowv)\}\)。......
  • 题解:CF2014D Robert Hood and Mrs Hood
    差分,每次差分将\(\max(1,l-d+1)\)加\(1\),将\(r+1\)位置减\(1\)。然后前缀和求原数组,再遍历一下求最小值和最大值即可。代码:#include<bits/stdc++.h>usingnamespacestd;intmain(){ intt; cin>>t; while(t--){ intn,d,k; cin>>n>>d>>k;......