zoukankan      html  css  js  c++  java
  • 模拟赛10.26题解

    Part 1

    难题部分:

    Day 1 Moring

    魔数

    【题目描述】
    小林和亮亮是好朋友。小林有一个幸运数字 a,亮亮有一个幸运数字 b。一
    个数字称之为“幸运数”当且仅当它只由 a 和 b 组成。小林称一个数为“魔数”,
    当且仅当这个数各数位之和为“幸运数”,且这个数字本身也是“幸运数”。
    举个例子:小林的幸运数字为 2,亮亮的幸运数字为 6,那么 23 不是“幸运
    数”,而 26、222 是“幸运数”。进一步,222 是“魔数”(因为 2+2+2=6),而 26
    不是“魔数”(因为 2+6=8)。
    亮亮想要知道,有多少个 n 位的“魔数”(一个 n 位数不包含前导 0),由于
    这个数字会很大,所以亮亮只关心这个数模 1000000007(10^9+7,是一个质数)
    的结果。
    【输入格式】
    只有一行,包含三个整数:a、b、n。意义见题目描述。
    【输出格式】
    只有一个整数,表示 n 位的“魔数”的个数模 1000000007 的结果。
    【样例输入】
    2 6 3
    【样例输出】
    1
    【样例解释】
    两个幸运数字分别为 2 和 6,则位数为 3 的“魔数”只有 222 一个。
    【数据规模】
    对于 30%的数据:1≤n≤5;
    对于 60%的数据:1≤n≤100;
    对于 100%的数据:1≤a<b≤9, 1≤n≤10^6。
    

    这道题给了做够的暴力分,通过dfs逐位数枚举再判断数位和是否为幸运数便可骗到三十分,但是如果换个角度,只要知道了幸运数,便可通过方程算出a,b的个数,若设有x个a,则有(n - x)个b,现在的幸运数为k,则有方程\(ax + b(n - x) = k\),解得到\(x\) = \(\frac{k - b * n}{a - b}\),又因为让a,b随意排列等于先放一种球到盒子里,另一种就固定了。

    注意到这道题值得学习的地方,首先是它的枚举幸运数的方式(我一开始就只想到dfs),我们可以知道幸运数的极大值为b * n,可以通过巧妙的\(- b + a\)使得b的数量减1,a的数量加1,循环变量i表示有多少个a在里面。还有再求同一底数的组合数时,用\(C_{n}^{i}\) = \(C_{n - 1}^{i}\) \(\times\) \(\frac{n - i + 1}{i}\)优化复杂度。

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    int a,b,n;
    const int Mod = 1e9 + 7;
    const int MAXN = 1e7 + 5;
    typedef long long ll;
    long long sum;
    long long ans;
    long long C[MAXN];
    bool check(long long k)
    {
    	bool flag = true;
    	while(k)
    	{
    		if(k % 10 != a && k % 10 != b)
    		{
    			flag = false;
    			return flag;
    		}
    		k /= 10;
    	}
    	return flag;
    }
    long long ksm(long long x,long long y)
    {
    	long long ans = 1;
    	while(y)
    	{
    		if(y & 1)ans = (ans * x) % Mod;
    		y >>= 1;
    		x = (x * x) % Mod;
    	}
    	return ans;
    }
    int main()
    {
    	scanf("%d %d %d", &a, &b, &n);
    	C[0] = 1;
    	for(int i = 1;i <= n; i++)
    		C[i] = ((C[i - 1] * ksm(i,Mod - 2) % Mod * (n - i + 1)) ) % Mod;
    	sum = b * n;
    	if(check(sum))ans++;
    	for(int i = 1;i <= n; i++)
    	{
    		sum = sum + a - b;
    		if(check(sum))ans += C[i];
    		ans %= Mod;
    	}
    	printf("%lld", ans);
    	return 0;
    }
    

    Day 1 Night(高精度专题)

    【高精度】e的n次方

    问题描述
        计算e的n次方,截断保留m位有效数字。
    输入格式
        只有一行n,m。
    输出格式
        只有一行,e的n次方的m位有效数字。
    样例输入
        样例输入1
        1 10
    
        样例输入2
        5 10
    样例输出
        样例输出1
        2.718281828
        样例输出2
        148.4131591
    提示
        n<=200,m<=10000
    

    公式:\(e^n=\sum_{k=0}^\infty \frac{n^k}{k!}\)

    本题思路比较明显,可以通过算增加量的方法计算e,可知增加的量为\(\frac{n}{i}\)(i为当前枚举到的k),因为有小数,只需将当前小数点位置记录,计算过程中小数点不会改变,将整个数乘10000就行了。
    注意:增量是由上次计算增量的值相乘而得,并非记录答案的数。

    代码(暂时只有80分,没有压位)

    #include <bits/stdc++.h>
    using namespace std;
    #define R register
    typedef long long ll;
    const int MAXN = 1e5 + 5;
    struct node
    {
    	short int a[MAXN],len;
    	inline void Clear()
    	{
    		memset(a,0,sizeof(a));
    		len = 0;
    	}
    	inline void read()
    	{
    		string s;
    		cin >> s;
    		len = s.size();
    		for(R int i = 1;i <= s.size(); i++)
    			a[i] = s[len - i] - '0';
    	}
    	inline node operator / (const ll &A)const
    	{
    		ll sum = 0;
    		node c;
    		c.Clear();
    		c.len = len;
    		for(R int i = len;i >= 1; i--)
    		{
    			sum = sum * 10 + a[i];
    			if(sum >= A)
    			{
    				c.a[i] = sum / A;
    				sum %= A;
    			}
    		}
    		while(c.a[c.len] == 0 && c.len > 1)
    			c.len--;
    		return c;
    	}
    	inline node operator * (const ll &A)const
    	{
    		node c;
    		c.Clear();
    		c.len = len;
    		ll sum = 0;
    		for(R int i = 1;i <= len; i++)
    		{
    			c.a[i] += a[i] * A;
    			c.a[i + 1] += c.a[i] / 10;
    			c.a[i] %= 10; 
    		}
    		while(c.a[c.len + 1] > 0)
    		{
    			c.len++;
    			c.a[c.len + 1] += c.a[c.len] / 10;
    			c.a[c.len] %= 10;
    		}
    		return c;
    	}
    	inline void write()
    	{
    		for(R int i = len;i >= 1; i--)
    			printf("%d", a[i]);
    	}
    	inline node operator + (const node &A)const
    	{
    		node ans;
    		ans.Clear();
    		ans.len = max(A.len,len);
    		for(R int i = 1; i <= ans.len; i++)
    		{
    			ans.a[i] += a[i] + A.a[i];
    			while(ans.a[i] >= 10)
    			{
    				ans.a[i] -= 10;
    				ans.a[i + 1]++;
    			}
    		}
    		while(ans.a[ans.len + 1] > 0)
    		{
    			ans.len++;
    		}
    		return ans;
    	}
    	inline bool cmpy(const node &A)
    	{
    		if(len != A.len)return false;
    		for(int i = len;i >= 0; i--)
    			if(a[i] != A.a[i])
    				return false;
    		return true;
    	}
    };
    int main()
    {
    	int m;
    	ll n;
    	scanf("%lld %d", &n, &m);
    	
    	node s;
    	s.len = 5000;
    	s.a[5000] = 1;
    	node Add,k,ans;
    	ans.a[5000] = 1;
    	ans.len = 1;
    	for(R ll i = 1;; i++)
    	{
    		k = ans;
    		s = s * n / i; 
    		ans = ans + s;
    		if(ans.cmpy(k) == true)break;
    	}
    	for(R int i = ans.len;i >= ans.len - m + 1; i--)
    	{
    		printf("%d", ans.a[i]);
    		if(i == 5000)
    			printf(".");
    	}
    	return 0;
    }
    
  • 相关阅读:
    echarts事件触发多次解决办法
    nginx代理出现的问题
    iframe页面之间通信
    获取当前日期的前XX天或者后XX天
    获取本月往后一年的日期月份信息
    Deltix Round, Summer 2021 (open for everyone, rated, Div. 1 + Div. 2)D. Take a Guess
    Deltix Round, Summer 2021 (open for everyone, rated, Div. 1 + Div. 2)C. Compressed Bracket Sequence
    Deltix Round, Summer 2021 (open for everyone, rated, Div. 1 + Div. 2)B. Take Your Places!
    Deltix Round, Summer 2021 (open for everyone, rated, Div. 1 + Div. 2) A. A Variety of Operations
    centos 查看mysql数据库命令
  • 原文地址:https://www.cnblogs.com/XuKeQAQ/p/13904921.html
Copyright © 2011-2022 走看看