TKK 20-21(2)第3次线上赛

伞兵代码,不吝赐教

1553:小数化分数

时间限制: 1 S | 内存限制: 8192 KB

描述

把一个纯小数(大于0且小于1)转换成最简分数形式。例如0.5=1/2。

输入

多组案例。一个正整数n,表示案例的数量。(n<=1000)

每组案例由一个小数点后最多18位的小数a构成。(a大于0且小于1)

输出

针对每组案例,输出a的最简分数表示形式b/c,其中b是分子,c是分母,中间用字符/间隔。

每组案例输出完都要换行。

样例输入

2

0.5

0.1000000007

样例输出

1/2

1000000007/10000000000

#include<iostream>
#include<string>
#include<cmath>
using namespace std;
typedef long long ll;
ll f(ll a, ll b)
{
	ll t;
	while (b != 0)
	{
		t = a % b;
		a = b;
		b = t;
	}
	return a;
}
int main()
{
	int n;
	cin >> n;
	int b[22];
	while (n--)
	{
		string a;
		cin >> a;
		int la = a.length();
		ll c = 0;
		for (int i = 2; i < la; i++)
		{
			b[i - 2] = a[la - 1 - i + 2] - '0';
		}
		int i = 0;
		for (; i < la - 2; i++)
		{
			c += ll(pow(10, i)) * b[i];//防止精度丢失
		}
		ll d;
			d = pow(10, i);
			ll p = f(c, d);
			ll x1 = c / p;
			ll x2 = d / p;
			cout << x1 << "/" << x2 << endl;
	}
}

1554:韩信点兵

时间限制: 1 S | 内存限制: 8192 KB

描述

相传韩信才智过人,从不直接清点自己军队的人数,只要让士兵先后以三人一排、五人一排、七人一排地变换队形,而他每次只掠一眼队伍的排尾就知道总人数了。例如三人一排余2,五人一排余1,七人一排余6,则符合条件的最小数字是41。

然而韩信觉得自己带兵应该是多多益善的,带多少兵都是有可能的,而不是局限于知道最小值为几。韩信还觉得每次固定按照三人、五人、七人数,会让士兵发觉他的计算技巧,不能制造神秘感。所以韩信会改变数人数的数量,并计算一定范围内满足条件的数字有多少个。

输入

多组案例。一个正整数n,表示案例的数量。(n<=20)

每组案例先是两个正整数a、b,分别表示士兵数量可能的范围是1~a,韩信数了b次。(1<=a<=1e18,1<=b<=9)

然后是b行数据,每行表示一次点兵的数据,由整数c和d组成,表示c人一排,最后剩d人。(1<=c<=100,0<=d<=c-1)

输出

针对每组案例,输出一个整数,表示1~a范围内(包括1和a),满足条件的数字有多少个。

每组案例输出完都要换行。

样例输入

2

200 3

3 2

5 1

7 6

200 3

3 2

5 1

6 0

样例输出

2

0

#include<iostream>
#include<string>
#include<cmath>
using namespace std;
typedef long long ll;
ll f(ll a, ll b)
{
	ll t;
	while (b != 0)
	{
		t = a % b;
		a = b;
		b = t;
	}
	return a;
}
int main()
{
	int n;
	cin >> n;
	while (n--)
	{
		ll a, b;
		cin >> a >> b;
		ll x[10], y[10], z[10];
		ll gcd = 1;
		for (int i = 0; i < b; i++)
		{
			cin >> x[i] >> y[i];
			gcd = gcd * x[i] / f(x[i], gcd);
			z[i] = gcd;
		}
		int cnt = 0;
		ll p = 0;
		ll e;
		if (y[0] == 0)e = x[0];
		else e = y[0];
		bool flag_ = false;
		for (int i = 0; i < b - 1; i++)
		{
			bool _flag = false;
			while (e <= z[i + 1])
			{
				bool flag = true;
				for (int j = 0; j <= i + 1; j++)
				{
					if (e % x[j] != y[j])//不符合
					{
						flag = false;
						break;
					}
				}
				if (flag) { _flag = true; break; }
				else e += z[i];
			}
			if (!_flag) { flag_ = true; break; }//找不到E
		}
		if (!flag_)
		{
			cout << (a - e) / gcd + 1 << endl;
		}
		else cout << 0 << endl;
	}
}

1555:回文数-1

时间限制: 1 S | 内存限制: 8192 KB

描述

如果一个数字从左往右读和从右往左读是相同的,则称该数字为回文数字。

已知两个正整数,问它们的总和是否构成回文数字。

输入

多组案例。一个正整数n,表示案例的数量。(n<=20)

每组案例由两个正整数a、b组成。(均不大于1e8)

输出

针对每组案例,如果a+b是回文数,则输出Yes,否则输出No。

每组案例输出完都要换行。

样例输入

3

99 11

120 1

35 53

样例输出

No

Yes

Yes

#include<iostream>
#include<string>
using namespace std;
int main()
{
    int n;
    cin >> n;
    while (n--)
    {
        int a[10] = { 0 }, b[10] = { 0 }, c[10] = { 0 };
        string x, y;
        cin >> x >> y;
        int la = x.length(), lb = y.length(), lc;
        for (int i = 0; i < la; i++)a[i] = x[la - 1 - i] - '0';
        for (int i = 0; i < lb; i++)b[i] = y[lb - 1 - i] - '0';
        int i;
        for (i = 0; i < la || i < lb; i++)
        {
            c[i] = c[i] + a[i] + b[i];
            if (c[i] > 9)c[i] -= 10, c[i + 1]++;
        }
        lc = i;
        if (c[lc] == 0)lc--;
        bool flag = true;
        for (int i = lc / 2; i >= 0; i--)
        {
            if (c[i] != c[lc - i])
            {
                flag = false;
                break;
            }
        }
        if (flag == true)cout << "Yes" << endl;
        else cout << "No" << endl;
    }
}

1556:回文数-2

时间限制: 1 S | 内存限制: 8192 KB

描述

如果一个数字从左往右读和从右往左读是相同的,则称该数字为回文数。

给定一个正整数a,求满足条件的最小非负整数b,使得a+b构成回文数。

输入

多组案例。一个正整数n,表示案例的数量。(n<=100)

每组案例有一个正整数a。(a<=1e15)

输出

针对每组案例,输出一个满足条件的最小非负整数b,使得a+b构成回文数。

每组案例输出完都要换行。

样例输入

2

88

113

样例输出

0

8


#include<iostream>
#include<string>
#include<cmath>
using namespace std;
typedef long long ll;
int main()
{
	int n;
	cin >> n;
	while (n--)
	{
		ll a, p;
		cin >> a;
		p = a;
		int b[17];
		int l;
		for (int i = 0; a > 0; i++)//逆序储存
		{
			b[i] = a % 10;
			a /= 10;
			l = i;
		}
		ll x=0, x_=0, y=0;
		for (int i = l / 2 + 1; i <= l; i++)//前半
		{
			x = x+b[i] * ll(pow(10, i - l / 2 - 1));
		}
		for (int i = l; i >= l / 2 + 1; i--)//前半逆序
		{
			x_ = x_+b[i] * ll(pow(10, l - i));
		}
		for (int i = 0; i <= (l + 1) / 2 - 1; i++)
		{
			y = y+b[i] * ll(pow(10, i));
		}
		if (x_ == y)
		{
			cout << 0;
		}
		else
		{
			if (x_ > y)
			{
				for (int i = 0; i <= (l + 1) / 2 - 1; i++)
				{
					b[i] = b[l-i];
				}
			}
			else
			{
				b[(l+1) / 2] += 1;
				for (int i =0; i <= l; i++)
				{
					if (b[i] > 9)
					{
						b[i] -= 10;
						b[i + 1] += 1;
					}
				}
				for (int i = 0; i <= (l + 1) / 2 - 1; i++)
				{
					b[i] = b[l - i];
				}
			}
			ll sum = 0;
			for (int i = 0; i <= l; i++)
			{
				sum = sum + b[i]*ll(pow(10, i));
			}
			cout << sum - p;
		}
		cout << endl;
	}
}

1557:源数

时间限制: 1 S | 内存限制: 8192 KB

描述

如果x的所有因数的和等于y,则称x是y的源数。

给定一个正整数a,求a的源数。

输入

多组案例。一个正整数n,表示案例的数量。(n<=50)

每组案例由一个正整数a构成。(a<=1000000)

输出

针对每组案例,输出一个整数,表示a的源数。如果有多个满足条件的源数,从小到大输出所有满足条件的源数,两两之间用一个空格字符隔开。如果没有满足条件的源数,则输出0。

每组案例输出完都要换行。

样例输入

3

12

3

5

样例输出

6 11

2

0

#include<iostream>
#include<string>
#include<cmath>
using namespace std;
typedef long long ll;
int a[1000002];
int main()
{
	for (int i = 1; i <= 1000002; i++)
	{
		for (int j = i; j <= 1000002; j += i)
		{
			a[j] += i;
		}
	}
	int n;
	cin >> n;
	while (n--)
	{
		int m;
		cin >> m;
		bool flag = true;
		bool flag_ = true;
		for (int i = 1; i <= 1000000; i++)
		{
			if (a[i] == m)
			{
				flag_ = false;
				if (flag) { cout << i; flag = false; }
				else cout << " " << i;
			}
		}
		if (flag_)cout << 0;
		cout << endl;
	}
}

1558:数字范围

时间限制: 4 S | 内存限制: 32768 KB

描述

有m个正整数(第1个、第2个、…、第m个),划掉其中第a个到第b个之间的所有数字(保证至少会留下一个数字),然后求剩下数字的最小值和最大值。

输入

只有一组案例。

一个正整数m,表示正整数的个数,(m<=1000000)

然后是m个正整数;(均不大于1e9)

接下来是一个正整数q,表示需要进行q次查询,(q<=10000)

每次查询由两个正整数a和b构成,表示本次查询不考虑第a个到第b个之间的所有数字。(1<=a<=b<=m)

输出

依次输出q行数据,表示q次查询的结果。

每行数据有两个整数,用空格间隔,表示在不考虑第a个到第b个之间所有数字的情况下,剩下数字的最小值和最大值。

每次查询输出完最小值和最大值后都要换行。

样例输入

6

3 10 2 7 3 5

2

2 5

1 2

样例输出

3 5

2 7

#include<iostream>
#include<string>
#include<cmath>
using namespace std;
typedef long long ll;
int a[1000005];
int l_max[1000005];
int l_min[1000005];
int r_max[1000005];
int r_min[1000005];
int main()
{
	int n;
	cin >> n;
	for (int i = 1; i <= n; i++)
	{
		cin >> a[i];
	}
	ll l_ma = 0, l_mi = 1000000000;
	for (int i = 1; i <= n; i++)
	{
		if (a[i] > l_ma)
		{
			l_ma = a[i];
		}
		l_max[i] = l_ma;
		if (a[i] < l_mi)
		{
			l_mi = a[i];
		}
		l_min[i] = l_mi;
	}
	ll r_ma = 0, r_mi = 1000000000;
	for (int i = n; i >= 1; i--)
	{
		if (a[i] > r_ma)r_ma = a[i];
		r_max[i] = r_ma;
		if (a[i] < r_mi)r_mi = a[i];
		r_min[i] = r_mi;
	}
	l_max[0] = 0;
	l_min[0] = 1000000001;
	r_max[n + 1] = 0;
	r_min[n + 1] = 1000000001;
	int m;
	cin >> m;
	while (m--)
	{
		int x, y;
		cin >> x >> y;
		int ma, mi;
		ma = max(l_max[x - 1], r_max[y + 1]);
		mi = min(l_min[x - 1], r_min[y + 1]);
		cout << mi << " " << ma << endl;
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值