近期模拟赛

大杂烩 订正了昂

或许这两天我有点水逆 牛客的比赛 大家觉得很简单的东西 我都不会写 我是不是最近要暴毙了??

这两天的比赛 补多少 写多少 不定更新

Day1 100+27+40

T1 一个数字串S 一个S打乱后的T串 用S - T 注意是转化后的数字相减 )考场上以为是 S到T 得到一个新的数字 然后随机抽一个数字 得到一个字符串P

现在给定P 那么求一组合法解以及删掉的数字 

其实算是一个构造题目吧

不过 这个很巧妙的小结论 大家还是有同学看出来的 我考场上按了好几遍计算器 我发现了这个东西 不过原来确实见过

也就是 对于 一个数字 他的每一位数字任意排列 将会得到一个新的数字 那么此时用较大的数字 减去 较小的数字 我们将会得到一个差值

那么这个差值 一定是9的倍数 那么 怎么找到这个数字 我们考虑 什么样子的数字是9的倍数

其实 我们要注重积累 我原来写计蒜客 普及 模拟赛 遇到一个题目 给你一个区间$[L,R]$ 这个区间的数字 L,L+1,L+2,....R 组在一起 构成一个数字

判断这个数字是不是9的倍数 L,R是1e12级别的

那么存在一个定理 是不是9的倍数 只需要判断 所有位的数字之和 是不是9的倍数即可 那么就是一个等差数列求和

为什么 正确呢 大家利用同余证明一下即可 其实 我很早发现9就是一个很神奇的数字 他的所有倍数 的 个位数 能把1-9都表示一边 看似没有用 

那么 考虑这个数字是谁 只需要所有位数字加起来 然后 % 9 再用 9 这个数字减去即可

那么 有的同学就开始暴搜全排列 qwq 不过 我们发现此时这个东西一个能表示成9x的形式 那么 10x-x=9x 题目允许前导零 所以我们直接求X即可

注意除的时候处理一下即可 放考场代码 qwq 不过乱搞有50 或者 80??

//打乱之后相减一定是9的倍数 
//构造10x-x=9x=num
//考虑删去的数字是什么 末尾添上一个数字 能 整除9 即可
#include<bits/stdc++.h>
using namespace std;
const int N=500100;
char p[N];
int main() {
    freopen("yukikaze.in","r",stdin);
    freopen("yukikaze.out","w",stdout);
    scanf("%s",p+1);
    int lenp=strlen(p+1);
    int ans=0;
    for(int i=1;i<=lenp;i++)
        ans+=(int)(p[i]-'0');
    int res=9-(ans%9);
    printf("%d\n",res);
    p[++lenp]=(char)(res+'0');
    res=0;
    for(int i=1;i<=lenp;i++) {
        res=res*10+(int)(p[i]-'0');
        p[i]=(char)((res/9)+'0');
        res%=9;
    }//求差
    for(int i=1;i<=lenp;i++) 
        printf("%d",(int)(p[i]-'0'));
    puts("0");//10倍即可 
    printf("0");
    for(int i=1;i<=lenp;i++)
        printf("%d",(int)(p[i]-'0'));
    return 0;
}
View Code

T2 对不起 我全场最低 27分

为什么呢 我小数据点的都T了 我看了好久 发现我没有(1)LCA 要哭了 

其实对于链的情况 确实很好推 

这里随便口胡一下 对于阶乘 以及 2^n 这些计数的理解 

首先 阶乘吧 就是带一种 全排列的思想在里面 没有任何限制的这种 我们一般知道有多少个位置 此时 没有限制的打乱 此时方案数就是阶乘

然后考虑 2^n 其实就是对应每个位置 都有两种选择 一共有n个位置 其实利用 乘法原理 不难发现

然后乘法原理 和 加法原理 大家 都会 就不管了

那么 对于一个长度是偶数的链 那么一定是前半部分 和 后半部分 匹配 此时方案数是 前半部分 * 后半部分 

那么 前半部分 是 (n/2)! 后半部分亦然 所以方案数是 (n/2)!*(n/2)!

那么链是偶数 此时 也是前半部分 和 后半部分 此时 考虑 中间那个数字 肯定是放哪无所谓 

所以 前半部分*后半部分*中间数字的方案数 答案就是 n *((n-1)/ 2))!*((n-1)/ 2)!

对于正解 我还没写 明天考虑 抽时间写一下

T3 暴搜+打表 

说实话 我信仰 14!能跑出来hh 结果等到他十几分钟hh

不过 有40分 还行吧 中低档水平

//暴搜+打表 考RP拿分 
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
template<typename T>inline void read(T &x) {
    x=0; T f=1,ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') f=-1; ch=getchar();}
    while(isdigit(ch))  {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    x*=f;
}
const int mod=1000000007;
ll n,ans=0,Sta[25],vis[25],tot[25],chosen[25],order[25];
inline int gcd(int a,int b){
    return b?gcd(b,a%b):a;
}
inline void dfs(int x) {
    if(x==n+1) {
        int res=0,s=0;
        memset(Sta,0,sizeof(Sta));
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=n;i++) {
            if(i==1) s=order[i],Sta[i]=s;
            else s=gcd(s,order[i]),Sta[i]=s;
//            cout<<s<<endl; 
        }
//        puts("");
        for(int i=1;i<=n;i++) {
            if(!vis[Sta[i]]) res++,vis[Sta[i]]=1;
        }
        tot[res]=(tot[res]+1)%mod;
//        cout<<tot[res]<<endl;
        if(ans<res) {
            ans=res;
        }
        return;
    }
    for(int i=1;i<=n;i++) {
        if(chosen[i]) continue;
        order[x]=i;
        chosen[i]=i;
        dfs(x+1);
        chosen[i]=0;
        order[x]=0;
    }
}
int main() {
//    freopen("1.in","r",stdin);
    freopen("shimakaze.in","r",stdin);
    freopen("shimakaze.out","w",stdout);
    read(n);
    if(n<=15) {
        if(n==2) puts("1");
        else if(n==6) puts("120");
        else if(n==7) puts("600");
        else if(n==8) puts("240");
        else if(n==9) puts("1440");
        else if(n==10) puts("15120");
        else if(n==11) puts("120960");
        else if(n==12) puts("7015680");
        else if(n==13) puts("69672960");
        else {
            dfs(1);
            printf("%d\n",tot[ans]);
        }
        return 0;
    } 
    else {
        if(n==25) puts("54818958");
        if(n==94657) puts("218873752");
        if(n==674591) puts("432028765");
        if(n==741964) puts("17832372");
    }
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/Tyouchie/p/11789467.html
今日推荐