zoukankan      html  css  js  c++  java
  • CODEFORCES #272 DIV2[为填完]

    #272是自己打的第一场cf,感觉这一套质量挺棒的,不像后两场略水

    //先附上A,B,C的题解,因为离noip只剩下一点时间了,所以之后不一定还刷cf,暂且就先放上前三题好了

    A题目大意忘了。懒得看,反正很水。

    B组合数学:

         题目大意:给你两个字符串;s1,s2

         其中s2字符串可能含有未知的字符,对于未知的字符你可以取+或者-,问你s2和s1相同的概率是多少?

         给字符串附上值;

         其中我们可规定+时,x++;-时,x--;并记录下有未知的字符有tot个,找到其中+有i个,- 有 tot-i个时,未知的字符串的值会等于已知

         然后运用排列组合的思想,计算 ans个选i个有多少种选法;C(ans,i)

         最后除以2^tot就为答案;

    附上代码:

       

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    using namespace std;
    char s1[50],s2[50];
    int l;
    int sum1,sum2;
    int ans,temp,f;
    double tot;
    int c(int m,int n){
    	int x=1,y=1;
    	double z;
    	for(int i=0;i<m;i++){
    		x*=(n-i);
    		y*=(m-i);
    	}
    	z=x/(y+0.0);
    	return z;
    }
    int main(){
    	//freopen("data.txt","r",stdin);
    	cin>>s1>>s2;
        l=strlen(s1);
    	for(int i=0;i<l;i++){
    		if(s1[i]=='+')  sum1++; else sum1--;
    		if(s2[i]=='+')  sum2++;
    		else if(s2[i]=='-') sum2--;
    		else ans++;
    	}	
    	temp=1;
    	for(int i=1;i<=ans;i++) temp*=2;
    	for(int i=0;i<=ans;i++){
    		if(sum2+i-(ans-i)==sum1){
    			f=c(i,ans);
    		    break;
    	    }
    	}
    	tot=f/(temp+0.0);
    	printf("%.12f",tot);
    	return 0;
    }
    

    C数论

          题目大意:给你a,b两个数,如果存在某个数 x 满足,mod(x,b)≠0且 div(x,b)/mod(x,b)=k,k属于[1,a]

          其中mod(x,b)=b%x;div(x,b)=b/x;

          问你所有可能的k的和是多少?

      

          好题啊....这套题貌似数学味道很重,D题瞥了眼貌似也是数论题;

          说说这题吧,我们可设

          x=y*b+z;z∈[0,b-1]

          如果想到了这一步,就差不多对了一半了(代码量太少了其实是)

          之后很自然的,我们会想到枚举z,也就是余数,以及枚举k,但是这很明显会超时;

          自己动手算几个,z一定时,x值的变化,我们会发现x不是一般的数列,而是等差数列!

          然后自己套个等差数列的公式即可;

    PS:但是因为取余的细节问题,WA了很多次;这里MARK一下:

    首先要知道虽是答案取余,但是是最终的答案取余么?明显不是。但是在运算过程中什么时候取余是很关键的,没有在适当的时候取余会导致结果错误;

    那么什么时候取余呢?正确的方法是,在每一个运算符之后;

    就比如: a*b+c让你对这个式子的答案取余。应该是这么算的: (a*b%mod+c)%mod

    但是这里还有一个很细节的地方:

    int a,b; a*b的值,就会保存在一个临时变量temp里,而且这个临时变量的类型也为int;

    但是,可能会出现 a*b的值在mod之前就已经爆int了,这时temp里存的值是有问题的,当然返回的值同样也会有问题,这样会导致答案错误;

    (你可以试一下这一题11这个点如果i为int 为发生什么)

    改进的方法就是,把a,b改为long long ,或是写成 1LL*a*b;

    建议还是用前面一种,因为后面一种在式子很长的情况下,极有可能会漏掉;

    附上代码:

    → Source
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    const long long mod=1e9+7;
    long long temp,ans,sum;
    long long a,b;
    int main(){
    	//freopen("data.txt","r",stdin);
    	scanf("%d%d",&a,&b);
    	for(long long i=1;i<b;i++){
    		ans=(ans+i*a%mod+a*(a+1)/2%mod*i%mod*b%mod)%mod;
    	}
    	cout<<ans;
    	return 0;
    }
    
  • 相关阅读:
    sl学习
    xc笔记
    1_2_3_4_5 Html-Css
    linux服务器架设--学习笔记
    注解学习
    关于ruby gem源更新安装问题
    css3:2D与3D变形
    css3关键帧动画以及兼容性策略
    css3背景,蒙版,倒影以及过度
    阴影边框以及渐变
  • 原文地址:https://www.cnblogs.com/polebug/p/4047196.html
Copyright © 2011-2022 走看看