首页 > 其他分享 >iwtgm-10

iwtgm-10

时间:2023-11-02 13:33:44浏览次数:27  
标签:prime 10 相同 ola int 质数 iwtgm 转移

题目链接

A.

手玩,左右循环后对应位置字符相同,可得到:
如果只有两个字符一定可以
如果是奇数,那么必须全部相同
如果是偶数,那么奇数位置的要全部相同,偶数位置的要全部相同

卡的点是相对位置不变,可以删除任意位置,如何判奇数全部相同,偶数全部相同
后来看@zys111代码,因为只有两种字符(可相同),可以用一个变量记录下一个需要的字符判

归纳,两个字符一定可以因为奇数只有一个,偶数只有一个,那么一定满足奇数位置和偶数位置分别相同
如果字符全部相同,那么也满足奇数位置和偶数位置分别相同,并且任意个数都可

void solve(){
    string s;cin>>s;
    int ans=inf,cnt,res;
    for(int i=0;i<=9;i++){
        for(int j=0;j<=9;j++){
            res=i;cnt=0;
            for(int k=0;k<s.size();k++){
                if(s[k]-'0'==res){
                    if(res==i)res=j;
                    else res=i;
                }else cnt++;
            }
            if(res==i)ans=min(ans,cnt);//两种不同字符的情况,两种字符数必须相同,此时变量为第一种字符的状态
        }
    }
    cout<<ans<<endl;
}

B.

求前n个数范围内有几个与i互质的和
欧拉函数可算对于i来说,在小于等于i的范围内有几个与i互质
欧拉筛法+欧拉函数可快速算出前n个数的欧拉函数的和
如果m<(n-1)或者m>这个和都不合法(必须要联通且这个和已经是最大的边数)直接退出
如果合法,m只有1e5,在n范围内暴力找与i互质的数输出即可

bool is_prime[N];//是否是质数,0为是,1为不是
int prime[N];//质数数组
int top=1;//质数的下标
int ola[N];//i的欧拉函数值
ll sum[N];//求1-n的欧拉函数的和
int gcd(int a, int b) {
    return b > 0 ? gcd(b, a % b) : a;
}
void get_prime(){
    ola[1]=1;
    for(int i=2;i<N;i++){
        if(!is_prime[i]){//是质数
            prime[top]=i;//存质数
            top++;//下标后移
            ola[i]=i-1;//质数的欧拉函数是质数-1
        }
        for(int j=1;j<top;j++){//最小到达遍历质数数组
            if(i*prime[j]>N)break;
            is_prime[i*prime[j]]=1;//标记质数的倍数即合数
            if(i%prime[j]==0){
                ola[i*prime[j]]=ola[i]*prime[j];//如果i%p==0,那么φ(i*p)=φ(i)*p
                break;//若i是之前质数的倍数,说明这个倍数会在后面的循环内被筛去,无需继续循环
            }
            ola[i* prime[j]]=ola[i]*(prime[j]-1);//如果i%p!=0,那么 φ(i*p)=φ(i)*(p-1)   其中p为质数
        }
    }
}
void solve(){
    get_prime();
    for(int i=1;i<N;i++){
        sum[i]+=sum[i-1]+1ll*ola[i];
    }
    int n,m;cin>>n>>m;
    if(n==1){
        cout<<"Impossible";return ;
    }
    if(m<(n-1)||m>sum[n]-1){
        cout<<"Impossible";return ;
    }
    //cout<<sum[n];
    cout<<"Possible"<<endl;
    int cnt=0;
    for(int i=1;i<=n;i++){
        for(int j=i+1;j<=n;j++){
            if(gcd(i,j)==1){
                cout<<i<<' '<<j<<endl;
                cnt++;
                if(cnt==m)return ;
            }
        }
    }
}

C.

若第一不要求一定要从0开始,
那么就是贪心,预处理出每个转移器的花费(a[i]+min(i,n-i+1)),然后排序从小到大取就好
因为每次用完转移器要么被转移到0要么转移到n+1,且我们用一个转移器的步数是固定的,转移到离下一个花费最少的转移器更近的点(0或n+1)即可
但现在要求第一步一定要从0开始,考虑如何消除这个影响
先按之前贪心的做法得到一个排序好的数组,对这个数组求一个前缀和,此时下标的值就是能取几个转移器,pre[i]就是总花费
可以枚举第一步选的是哪一个转移器,设下标为id,用花费-差价(没有实际减,只是用这个值去二分)(贪心最优和从0到这个转移器),
此时二分看前缀和数组下标能取到几,设为p,如果p>id,说明此时花费已经包含了我枚举的第一个转移器(这里是贪心取),但差价已经计算过了,下标-1就是答案(因为upper_bound()取的是大于花费的)
如果p<=id,说明没有算第一步的转移器,那么把花费-枚举的那个转移器的花费后再去二分
得到的下标p不用-1因为多的那个1与枚举的那个1抵消

ll n,c,pre[N],ans,cnt;
pair<ll,ll>pa[N];
void solve(){
    ans=0;cin>>n>>c;
    for(ll i=1,x;i<=n;i++){
        cin>>x;
        pa[i]={x+min(i,n-i+1),x+i};
    }
    sort(pa+1,pa+1+n);
    for(int i=1;i<=n;i++)pre[i]=pre[i-1]+pa[i].first;
    for(int i=1;i<=n;i++){
        if(c<pa[i].second)continue;
        cnt= upper_bound(pre+1,pre+1+n,c-pa[i].second+pa[i].first)-pre-1;//upper_bound()给出的下标是大于花费的,所以-1
        if(cnt<i)cnt= upper_bound(pre+1,pre+1+n,c-pa[i].second)-pre;//大于花费的那个1与枚举的那个1抵消,不用-1
        ans=max(ans,cnt);
    }
    cout<<ans<<endl;
}

标签:prime,10,相同,ola,int,质数,iwtgm,转移
From: https://www.cnblogs.com/wwww-/p/17805185.html

相关文章

  • iwtgm-9
    题目链接dp,自己写的时候没有考虑完全状态转移,其实是滑动窗口dp,需要维护一段区间的最小值1-n内的数显然能一步得到,考虑n+1到y,可由前面的状态加数得到也可以乘数得到,考虑加,其实是区间长度为n的滑动窗口的最小值+1考虑乘,若当前数i能整除mi,则dp[mi]+1inta[N],dp[N],q[N],tt=-1,......
  • iwtgm-8
    题目链接A.模拟,先遍历一遍,出现0,则i+x和i-x存在则必是0再遍历一遍,出现1,判i+x和i-x位上若已经是1或还没被赋值则满足题意,否则失败退出输出是当前位是1,则输出1,否则输出0.因为1的限制范围明确,其余都填0voidsolve(){strings;cin>>s;intx;cin>>x;charc[N];......
  • 力扣2610. 转换二维数组(哈希表)
    给你一个整数数组 nums 。请你创建一个满足以下条件的二维数组:二维数组应该 只 包含数组 nums 中的元素。二维数组中的每一行都包含 不同 的整数。二维数组的行数应尽可能 少 。返回结果数组。如果存在多种答案,则返回其中任何一种。请注意,二维数组的每一行上可以......
  • crypto 2023.10.31-11.05
    1.a.题目后面有"="就先猜一手base64编码,直接复制base64解码解密即可得到flagb.故直接用工具进行解密 2. a.因为是MD5加密,故直接用工具解密 3. a.因为是Url加密,故直接用工具解密 4. a.看题目像是凯撒密码,直接使用工具,并找到flag  5. a.因为key{}里面......
  • Windows10下用Anaconda3安装TensorFlow教程
    安装好了Anaconda3—后,运行开始菜单—>Anaconda3—>AnacondaPrompt##CPUpip3installtensorflow-ihttps://pypi.tuna.tsinghua.edu.cn/simple/##GPUpip3installtensorflow-gpu-ihttps://pypi.tuna.tsinghua.edu.cn/simple/##TESTimporttensorflowastfhello=......
  • 【2023-10-21】书柜到了
    20:00劝人不可指其过,须先美其长;人喜则语言易入,怒则语言难入。                                                 ——XXX昨晚临下班前,收到快递到了站点的配送通知。是......
  • 【2023-10-22】连岳摘抄
    23:59才华是刀刃,辛苦是磨刀石,再锋利的刀刃,若日久不磨,也会生锈。                                                 ——老舍市场逻辑本能地追求赢者通吃,永远增长。当......
  • 2103. 环和杆
    1.题目总计有n个环,环的颜色可以是红、绿、蓝中的一种。这些环分别穿在10根编号为0到9的杆上。给你一个长度为2n的字符串rings,表示这n个环在杆上的分布。rings中每两个字符形成一个颜色位置对,用于描述每个环:第i对中的第一个字符表示第i个环的颜色('R'、'......
  • for语句练习(打印1-10)
    #include<stdio.h>#include<stdlib.h>intmain(){  inti=0;  for(i=1;i<=10;i++)//i=1为初始化部分;i<=10为判断部分;i++为调整部分  {    printf("%d",i);  }  return0;}......
  • for语句与while语句对比(打印1-10)(加入continue)
    //for#include<stdio.h>intmain(){  inti=0;  for(i=1;i<=10;i++)  {    if(i==5)      continue;    printf("%d",i);  }  return0;}//结果为1234 678910//while#include<stdio.h>intmain(){ ......