#省赛模拟题分析(倒计时19天自救计划)

鸡汤一手

CCPC网络赛选拔女队F0258总排名25名,总排名800名多点。
总结分析:
那天队友各出了两道题,我出了一道博弈论的难题。
上来随便选一题做结果就选到了10%通过率的我也是够黑的。
总共出了五道题。
问题主要在于罚时太高,从480名开始出题数和我们都是一样的,但是队友出的题并没有罚时上的优势,我那道题更是提交了8次。
那道博弈论的题目其实是现学现用的sg函数和Nim,但是假如这题没做出来我们就是1900名。
因为无论是四题还是五题的出题量,我们的罚时都是很高的。
看来正式比赛还是尽可能要多出一题,但是博弈论这种东西,太难保证,dp方面又是老大难。但也没办法,机会来了抓不住想想也是自己捞。
主要任务:
完善优化板子并且熟练接口,用win的电脑编译适应比赛环境。
熟练dp和概率论数学几何相关。
不过题目也是离谱,B题直接一个min25筛板子题????
神经病。
不过有比赛名额就好,可惜因为疫情错失了秦皇岛的公费旅游,伤心了。
10月18日比赛加油!


省赛模拟9.24

A - Marjar Cola

Marjar Cola is on sale now! In order to attract more customers, Edward, the boss of Marjar Company, decides to launch a promotion: If a customer returns x empty cola bottles or y cola bottle caps to the company, he can get a full bottle of Marjar Cola for free!
Now, Alice has a empty cola bottles and b cola bottle caps, and she wants to drink as many bottles of cola as possible. Do you know how many full bottles of Marjar Cola she can drink?
Note that a bottle of cola consists of one cola bottle and one bottle cap.
Input
There are multiple test cases. The first line of input contains an integer T (1 ≤ T ≤ 100), indicating the number of test cases. For each test case:
The first and only line contains four integers x, y, a, b (1 ≤ x, y, a, b ≤ 100). Their meanings are described above.
Output
For each test case, print one line containing one integer, indicating the number of bottles of cola Alice can drink. If Alice can drink an infinite number of bottles of cola, print “INF” (without the quotes) instead.
Sample Input
2
1 3 1 1
4 3 6 4
Sample Output
INF
4
Hint
For the second test case, Alice has 6 empty bottles and 4 bottle caps in hand. She can return 4 bottles and 3 caps to the company to get 2 full bottles of cola. Then she will have 4 empty bottles and 3 caps in hand. She can return them to the company again and get another 2 full bottles of cola. This time she has 2 bottles and 2 caps in hand, but they are not enough to make the exchange. So the answer is 4.

题意解释
x个瓶子或y个瓶盖换一瓶可乐,你有a个瓶子,b个瓶盖,最多能换多少可乐。
x/y有1或者两个2并且a b之和大于等于3的情况为无限。
这点自己画画看。
反正嗯模,就嗯模。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <set>
#include <stack>
#include <queue>
#include <string>
#include <cstring>
#include <iomanip>
#define ll long long
using namespace std;
const int MAX = 1e5 + 10;
const int INF = 1e9 + 7;

int main() {
    int T;
    scanf("%d", &T);
    while(T--) {
        int x, y, a, b;
        scanf("%d%d%d%d", &x, &y, &a, &b);
        if(x == 1|| y == 1 || (x == 2 && y == 2 && a >= 2)|| (x == 2 && y == 2 && b >= 2)) {
            printf("INF\n");
            continue;
        }
        int ans = 0;
        while(1) {
            if(a < x && b < y) break;
            while(a >= x) {
                int cnt = a / x;
                ans += cnt;
                a %= x;
                a += cnt;
                b += cnt;
            }
            while(b >= y) {
                int cnt = b / y;
                ans += cnt;
                b %= y;
                a += cnt;
                b += cnt;
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}

C - How Many Nines

If we represent a date in the format YYYY-MM-DD (for example, 2017-04-09), do you know how many 9s will appear in all the dates between Y1-M1-D1 and Y2-M2-D2 (both inclusive)?
Note that you should take leap years into consideration. A leap year is a year which can be divided by 400 or can be divided by 4 but can’t be divided by 100.
Input
The first line of the input is an integer T (1 ≤ T ≤ 105), indicating the number of test cases. Then T test cases follow. For each test case:
The first and only line contains six integers Y1, M1, D1, Y2, M2, D2, their meanings are described above.
It’s guaranteed that Y1-M1-D1 is not larger than Y2-M2-D2. Both Y1-M1-D1 and Y2-M2-D2 are between 2000-01-01 and 9999-12-31, and both dates are valid.
We kindly remind you that this problem contains large I/O file, so it’s recommended to use a faster I/O method. For example, you can use scanf/printf instead of cin/cout in C++.
Output
For each test case, you should output one line containing one integer, indicating the answer of this test case.
Sample Input
4
2017 04 09 2017 05 09
2100 02 01 2100 03 01
9996 02 01 9996 03 01
2000 01 01 9999 12 31
Sample Output
4
2
93
1763534
Hint
For the first test case, four 9s appear in all the dates between 2017-04-09 and 2017-05-09. They are: 2017-04-09 (one 9), 2017-04-19 (one 9), 2017-04-29 (one 9), and 2017-05-09 (one 9).
For the second test case, as year 2100 is not a leap year, only two 9s appear in all the dates between 2100-02-01 and 2100-03-01. They are: 2017-02-09 (one 9) and 2017-02-19 (one 9).
For the third test case, at least three 9s appear in each date between 9996-02-01 and 9996-03-01. Also, there are three additional nines, namely 9996-02-09 (one 9), 9996-02-19 (one 9) and 9996-02-29 (one 9). So the answer is 3 × 30 + 3 = 93.

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <set>
#include <stack>
#include <queue>
#include <string>
#include <cstring>
#include <iomanip>
#define ll long long
using namespace std;
const int MAX = 1e4 + 10;
const int INF = 1e9 + 7;

int a[13];
int year[MAX];
int run[MAX];
int sumday[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

inline void init() {
    for(int i = 1; i <= 12; i++) {
        a[i] = 3;
    }
    a[2] = 2;
    a[9] = 33;

    run[1999] = 0;
    int cnt = 0;
    for(int i = 1999; i <= 10000; i++) {
        if(i % 400 == 0 || (i % 100 != 0 && i % 4 == 0)) {
            cnt++;
        }
        run[i] = cnt;
        int cnt9 = 0;
        if(i % 10 == 9) cnt9++;
        if(i / 10 % 10 == 9) cnt9++;
        if(i / 100 % 10 == 9) cnt9++;
        if(i / 1000 % 10 == 9) cnt9++;
        year[i] = cnt9;
    }

    for(int i = 1; i <= 12; i++) {
        sumday[i] += sumday[i - 1];
    }

}

ll solve(int y1, int y2) {//闭区间
    ll ans = 0ll;
    for(int i = y1; i < y2; i++) {
        if(run[i] > run[i - 1]) {
            ans += (366) * year[i] + 66;
        }
        else ans += 365 * year[i] + 65;
    }
    return ans;
}

int main() {
    init();
    int T;
    scanf("%d", &T);
    while(T--) {
        int y1, m1, d1, y2, m2, d2;
        scanf("%d%d%d %d%d%d", &y1, &m1, &d1, &y2, &m2, &d2);
        ll ans = 0ll;
        //开区间
        d1--;

        ans += solve(y1, y2);
        //-前面的
        ans -= (sumday[m1 - 1] + d1) * year[y1];
        if(run[y1] > run[y1 - 1] && m1 >= 3) ans -= year[y1];
        //cout << " -年: "<< ans << endl;
        //月
        for(int i = 1; i < m1; i++) ans -= a[i];
        if(run[y1] > run[y1 - 1] && m1 >= 3) ans -= 1;
       // cout << " -月: "<< ans << endl;
        //日
        if(m1 == 9) {
            ans -= d1;
        }
            if(d1 >= 29) ans -= 3;
            else if(d1 >= 19) ans -= 2;
            else if(d1 >= 9) ans--;


        //cout << " -日: "<< ans << endl;

        //+后面的
        //年
        ans += (sumday[m2 - 1] + d2) * year[y2];
        if(run[y2] > run[y2 - 1] && m2 >= 3) ans += year[y2];
        //cout << " +年: "<< ans << endl;

        //月
        for(int i = 1; i < m2; i++) ans += a[i];
        if(run[y2] > run[y2 - 1] && m2 >= 3) ans += 1;
        //cout << " +月: "<< ans << endl;

        //日
        if(m2 == 9) {
            ans += d2;
        }
            if(d2 >= 29) ans += 3;
            else if(d2 >= 19) ans += 2;
            else if(d2 >= 9) ans++;

        //cout << " +日: "<< ans << endl;
        printf("%lld\n", ans);
    }
    return 0;
}

题意分析
大模拟
就嗯模拟。
注意的是闰年2月多一个29,以及同年九月份日期间9个数的计算。


F - Intervals

Chiaki has n intervals and the i-th of them is [li, ri]. She wants to delete some intervals so that there does not exist three intervals a, b and c such that a intersects with b, b intersects with c and c intersects with a.
Chiaki is interested in the minimum number of intervals which need to be deleted.
Note that interval a intersects with interval b if there exists a real number x such that la ≤ x ≤ ra and lb ≤ x ≤ rb.
Input
There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:
The first line contains an integer n (1 ≤ n ≤ 50000) – the number of intervals.
Each of the following n lines contains two integers li and ri (1 ≤ li < ri ≤ 109) denoting the i-th interval. Note that for every 1 ≤ i < j ≤ n, li ≠ lj or ri ≠ rj.
It is guaranteed that the sum of all n does not exceed 500000.
Output
For each test case, output an integer m denoting the minimum number of deletions. Then in the next line, output m integers in increasing order denoting the index of the intervals to be deleted. If m equals to 0, you should output an empty line in the second line.
Sample Input
1
11
2 5
4 7
3 9
6 11
1 12
10 15
8 17
13 18
16 20
14 21
19 22
Sample Output
4
3 5 7 10

题意分析
题意:问至少删除多少个区间才能保证剩下来的区间不会有三个及其以上的重叠。
思路:先将区间按右端点从小到大排序,记录一下重叠了两次的最右端位置right,然后就嗯做咯。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <cstring>
#include <list>
#include <queue>
#include <stack>
#include <set>
#include <algorithm>
#include <cmath>
#include <set>
#include <map>
#include <iomanip>

#define INF 0x3f3f3f3f
#define pi acos(-1)
const int N=5e4+7;
using namespace std;
typedef long long ll;
typedef pair<int, int> P;

int ans[N];
struct node{
    int a,b,idx;
}qiuxia[N];
//用我可爱的舍友作为变量名

bool cmp(node a, node b)
{
    if (a.a != b.a) return a.a < b.a;
    else return a.b < b.b;
}

bool cmp2(node a, node b)
{
    if (a.b != b.b) return a.b > b.b;
    else return a.a < b.a;
}

bool isxiangjiao(node x, node y, node z)
{
    bool f1 = y.a <= x.b;
    bool f2 = (z.a <= x.b) && (z.a <= y.b);
    if (f1 && f2) return true;
    else return false;
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int T;
    cin >> T;
    while(T--)
    {
        int n;
        cin>>n;
        for (int i = 0; i < n; i++)
        {
            cin>>qiuxia[i].a>>qiuxia[i].b;
            qiuxia[i].idx = i + 1;
        }
        sort(qiuxia, qiuxia + n, cmp);
        node x[5];
        x[0] = qiuxia[0]; x[1] = qiuxia[1];
        int pos = 0;
        for (int i = 2; i < n; i++)
        {
            x[2] = qiuxia[i];
            sort(x, x + 3, cmp);
            int f = isxiangjiao(x[0],x[1],x[2]);
            sort(x, x + 3, cmp2);
            if (f)
            {
                ans[pos++] = x[0].idx;
                swap(x[0],x[2]);
            }

        }
        sort(ans, ans + pos);
        cout << pos << endl;
        if (pos > 0) cout << ans[0];
        for (int i = 1; i < pos; i++) cout << " " << ans[i];
        cout << endl;
    }
    return 0;
}

G - Seven-Segment Display

A seven segment display, or seven segment indicator, is a form of electronic display device for displaying decimal numerals that is an alternative to the more complex dot matrix displays. Seven segment displays are widely used in digital clocks, electronic meters, basic calculators, and other electronic devices that display numerical information.
The segments of a seven segment display are arranged as a rectangle of two vertical segments on each side with one horizontal segment on the top, middle, and bottom. If we refer the segments as the letters from a to g, it’s possible to use the status of the segments which is called a seven segment code to represent a number. A standard combination of the seven segment codes is shown below.
X a b c d e f g
1 1 0 0 1 1 1 1
2 0 0 1 0 0 1 0
3 0 0 0 0 1 1 0
4 1 0 0 1 1 0 0
5 0 1 0 0 1 0 0
6 0 1 0 0 0 0 0
7 0 0 0 1 1 1 1
8 0 0 0 0 0 0 0
9 0 0 0 0 1 0 0
0 = on 1 = off

在这里插入图片描述

A seven segment code of permutation p is a set of seven segment code derived from the standard code by rearranging the bits into the order indicated by p. For example, the seven segment codes of permutation “gbedcfa” which is derived from the standard code by exchanging the bits represented by “a” and “g”, and by exchanging the bits represented by “c” and “e”, is listed as follows.
X g b e d c f a
1 1 0 1 1 0 1 1
2 0 0 0 0 1 1 0
3 0 0 1 0 0 1 0
4 0 0 1 1 0 0 1
5 0 1 1 0 0 0 0
6 0 1 0 0 0 0 0
7 1 0 1 1 0 1 0
8 0 0 0 0 0 0 0
9 0 0 1 0 0 0 0
We indicate the seven segment code of permutation p representing number x as cp, x. For example cabcdefg,7 = 0001111, and cgbedcfa,7 = 1011010.
Given n seven segment codes s1, s2, … , sn and the numbers x1, x2, … , xn each of them represents, can you find a permutation p, so that for all 1 ≤ i ≤ n, si = cp, xi holds?
Input
The first line of the input is an integer T (1 ≤ T ≤ 105), indicating the number of test cases. Then T test cases follow.
The first line of each test case contains an integer n (1 ≤ n ≤ 9), indicating the number of seven segment codes.
For the next n lines, the i-th line contains a number xi (1 ≤ xi ≤ 9) and a seven segment code si (|si| = 7), their meanings are described above.
It is guaranteed that ∀ 1 ≤ i < j ≤ n, xi ≠ xj holds for each test case.
Output
For each test case, output “YES” (without the quotes) if the permutation p exists. Otherwise output “NO” (without the quotes).
Sample Input
3
9
1 1001111
2 0010010
3 0000110
4 1001100
5 0100100
6 0100000
7 0001111
8 0000000
9 0000100
2
1 1001111
7 1010011
2
7 0101011
1 1101011
Sample Output
YES
NO
YES
Hint
For the first test case, it is a standard combination of the seven segment codes.
For the second test case, we can easily discover that the permutation p does not exist, as three in seven bits are different between the seven segment codes of 1 and 7.
For the third test case, p = agbfced.

题意分析
问题在于,其实竖着看列是不变的,只是排列顺序有改变。
老实说,其实还是嗯模拟。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <set>
#include <stack>
#include <queue>
#include <string>
#include <cstring>
#include <iomanip>

#define ll long long
using namespace std;
using namespace std;
const int MAXN = 1e5 + 7;
int OK[10][7] = {{},
                {1, 0, 0, 1, 1, 1, 1},
                {0, 0, 1, 0, 0, 1, 0},
                {0, 0, 0, 0, 1, 1, 0},
                {1, 0, 0, 1, 1, 0, 0},
                {0, 1, 0, 0, 1, 0, 0},
                {0, 1, 0, 0, 0, 0, 0},
                {0, 0, 0, 1, 1, 1, 1},
                {0, 0, 0, 0, 0, 0, 0},
                {0, 0, 0, 0, 1, 0, 0}};
char s[8];
bool vis[7];
int qiu[7], yao[7];
//我亲爱的队友们
struct node {
    int numb;
    int source[7];
} a[10];

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int T, n;
    cin >> T;
    while (T--) {
        memset(vis, 0, sizeof(vis));
        cin >> n;
        for (int i = 1; i <= n; i++) {
            cin >> a[i].numb >> s;
            for (int j = 0; j < 7; j++)
                a[i].source[j] = s[j] - '0';
        }

        for (int i = 0; i < 7; i++) {
            int cnt = 0;
            for (int j = 1; j <= n; j++)
                cnt += pow(a[j].source[i] * 2, a[j].numb);
            qiu[i] = cnt;

        }
        for (int i = 0; i < 7; i++) {
            int cnt = 0;
            for (int j = 1; j <= n; j++) {
                cnt += pow(OK[a[j].numb][i] * 2, a[j].numb);
            }

            yao[i] = cnt;
        }

        int ans = 0;
        for (int i = 0; i < 7; i++) {
            for (int j = 0; j < 7; j++) {
                if (qiu[i] == yao[j] && !vis[j]) {
                    ans++;
                    vis[j] = true;
                    break;
                }
            }
        }

        if (ans == 7)
           cout<<"YES\n";
        else
            cout<<"NO\n";
    }
}

I - Course Selection System
终于有道dp能做了

There are n courses in the course selection system of Marjar University. The i-th course is described by two values: happiness Hi and credit Ci. If a student selects m courses x1, x2, …, xm, then his comfort level of the semester can be defined as follows:
( ∑ i = 1 m H x i ) 2 − ( ∑ i = 1 m H x i ) × ( ∑ i = 1 m C x i ) − ( ∑ i = 1 m C x i ) 2 (\sum_{i=1}^{m} H_{x_i})^2-(\sum_{i=1}^{m} H_{x_i})\times(\sum_{i=1}^{m} C_{x_i})-(\sum_{i=1}^{m} C_{x_i})^2 (i=1mHxi)2(i=1mHxi)×(i=1mCxi)(i=1mCxi)2
Edward, a student in Marjar University, wants to select some courses (also he can select no courses, then his comfort level is 0) to maximize his comfort level. Can you help him?
Input
There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:
The first line contains a integer n (1 ≤ n ≤ 500) – the number of cources.
Each of the next n lines contains two integers Hi and Ci (1 ≤ Hi ≤ 10000, 1 ≤ Ci ≤ 100).
It is guaranteed that the sum of all n does not exceed 5000.
We kindly remind you that this problem contains large I/O file, so it’s recommended to use a faster I/O method. For example, you can use scanf/printf instead of cin/cout in C++.
Output
For each case, you should output one integer denoting the maximum comfort.
Sample Input
2
3
10 1
5 1
2 10
2
1 10
2 10
Sample Output
191
0
Hint
For the first case, Edward should select the first and second courses.
For the second case, Edward should select no courses.

题意描述
题意:
t 组数据,每组给出 n 门课,第 i 门课给出两个值 Hi、Ci,对于每门课可以选也可以不选,最后要求算一个结果,其计算公式如上,其中 m 是所有选的课,求最大的结果。
思路:
对于所给公式,化简后有:res=-C^2+H(H-C)
即令 H 尽量大,C 尽量小。
再考虑第 i 门课可以放也可以不放。
那么原问题可以转化为 01 背包问题,即:对于第 i 物品来说,可以选也可以不选,令 Hi 为物品价值,Ci 为物品重量,物品重量从 1 到 500*100=50000,最后枚举结果的最大值即可
要注意的是,由于所有的课都可以不选,那么结果的最小值最小为 0,不可能为负数。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>

using namespace std;
typedef long long ll;
const int maxn = 5e4 + 5;
const ll INF = 0x3f3f3f3f;
int h[505], c[505];
ll dp[maxn];

int main() {
    int T;
    scanf("%d", &T);
    while (T--) {
        memset(dp, 0, sizeof(dp));
        int n;
        int sum=0;
        scanf("%d", &n);
        for (int i = 1; i <= n; i++) {
            scanf("%d %d", &h[i], &c[i]);
            sum+=c[i];
        }
        for (int i = 1; i <= n; i++) {
            for (int j = sum; j >= c[i]; j--) {
                if (dp[j] <= dp[j - c[i]] + h[i])
                    dp[j] = dp[j - c[i]] + h[i];
                  
           //我的dp数组存的不是最终答案,而是现有C下最大的H
            }
        }

        ll ans = 0;
        for (ll i = 1; i <= maxn; i++) {
            if (dp[i] > 0)
     ans = max(dp[i] * dp[i] - dp[i] * i - i * i, ans);
        }
        printf("%lld\n", ans);
    }
    return 0;
}

J - Knuth-Morris-Pratt Algorithm

In computer science, the Knuth-Morris-Pratt string searching algorithm (or KMP algorithm) searches for occurrences of a “word” W within a main “text string” S by employing the observation that when a mismatch occurs, the word itself embodies sufficient information to determine where the next match could begin, thus bypassing re-examination of previously matched characters.
Edward is a fan of mathematics. He just learnt the Knuth-Morris-Pratt algorithm and decides to give the following problem a try:
Find the total number of occurrence of the strings “cat” and “dog” in a given string s.
As Edward is not familiar with the KMP algorithm, he turns to you for help. Can you help Edward to solve this problem?
Input
There are multiple test cases. The first line of input contains an integer T (1 ≤ T ≤ 30), indicating the number of test cases. For each test case:
The first line contains a string s (1 ≤ |s| ≤ 1000).
Output
For each case, you should output one integer, indicating the total number of occurrence of “cat” and “dog” in the string.
Sample Input
7
catcatcatdogggy
docadosfascat
dogdddcat
catcatcatcatccat
dogdogdogddddooog
dcoagtcat
doogdog
Sample Output
4
1
2
5
3
1
1
Hint
For the first test case, there are 3 “cat” and 1 “dog” in the string, so the answer is 4.
For the second test case, there is only 1 “cat” and no “dog” in the string, so the answer is 1.

题意分析
字符串查找嘛,无脑kmp板子。
这种字符串题目一般都是我亲爱的队友做,我敲不来。


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <cstring>
#include <list>
#include <queue>
#include <stack>
#include <set>
#include <algorithm>
#include <cmath>
#include <set>
#include <map>
#include <iomanip>
#define INF 0x3f3f3f3f
#define pi acos(-1)
#define N 1000005
typedef unsigned long long ll;
using namespace std;

char ans[N];
int nxt[N];

void get_next(char *T)
{
    nxt[0] = -1;
    int i = 0, j = -1;
    int len = strlen(T);
    while(i < len)
    {
        if(j == -1 || T[i] == T[j])
            nxt[++i] = ++j;
        else
            j = nxt[j];
    }
}

int KMP(char* S, char* T)
{
    get_next(T);
    int res = 0;
    int len1 = strlen(T);
    int len2 = strlen(S);
    int i = 0, j = 0;           //i指向模式串T,j指向主串S
    while(j < len2)
    {
        if(T[i] == S[j])
        {
            i++;
            j++;
            if(i == len1)
            {
                //return j - i + 1;
                res++;
            }
        }
        else
        {
            i = nxt[i];
            if(i == -1)
            {
                j++;
                i++;
            }
        }
    }
    return res;
}
    char s1[5] = {"cat"}, s2[5] = {"dog"};
    char str[N];
int main()
{
    int T;
    scanf("%d", &T);
    while(T--)
    {
        scanf("%s", str);
        ll ans = KMP(str, s1);
        ans += KMP(str, s2);
        printf("%lld\n", ans);
    }
    return 0;
}

——————————————————————————
1.洛谷P1017 进制转换

题目描述
我们可以用这样的方式来表示一个十进制数: 将每个阿拉伯数字乘以一个以该数字所处位置为指数,以 1010 为底数的幂之和的形式。例如 123123 可表示为在这里插入图片描述 这样的形式。
与之相似的,对二进制数来说,也可表示成每个二进制数码乘以一个以该数字所处位置为指数,以 22 为底数的幂之和的形式。
一般说来,任何一个正整数 RR 或一个负整数 -R−R 都可以被选来作为一个数制系统的基数。如果是以 RR 或 -R−R 为基数,则需要用到的数码为 0,1,…R-10,1,…R−1。
例如当 R=7R=7 时,所需用到的数码是 0,1,2,3,4,5,60,1,2,3,4,5,6,这与其是 RR 或 -R−R 无关。如果作为基数的数绝对值超过 1010,则为了表示这些数码,通常使用英文字母来表示那些大于 99 的数码。例如对 1616 进制数来说,用 AA 表示 1010,用 BB 表示 1111,用 CC 表示 1212,以此类推。
在负进制数中是用 -R−R 作为基数,例如 -15−15(十进制)相当于 110001110001 (-2−2进制),并且它可以被表示为 22 的幂级数的和数:
在这里插入图片描述
设计一个程序,读入一个十进制数和一个负进制数的基数, 并将此十进制数转换为此负进制下的数。
输入格式
输入的每行有两个输入数据。
第一个是十进制数 nn。 第二个是负进制数的基数 -R−R。
输出格式
输出此负进制数及其基数,若此基数超过 1010,则参照 1616 进制的方式处理。
在这里插入图片描述

解题思路
负进制!!!
你要说重点其实就是负进制的情况下余数也不能小于0
(商+1)*除数+(余数-除数)=商*除数+除数+余数-除数 =商*除数+余数=被除数
因为我们是不断取余数倒序为转换结果,所以余数不能出现负数
需要将商+1,余数-除数即可,因为余数(绝对值)一定小于除数,所以这样就可以将余数装换为正数
重点:如果余数<0,那么:余数-=m;商++;懂就会,不懂就不会。

if (k < 0) {
k -= b;
n += 1;
}
if (k > 9)
c[i] = char(k - 10 + ‘A’);
else c[i] = char(k + ‘0’);
i++;

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <cstring>
#include <list>
#include <queue>
#include <stack>
#include <set>
#include <algorithm>
#include <cmath>
#include <set>
#include <map>
#include <iomanip>

#define INF 0x3f3f3f3f
#define pi acos(-1)
#define N 66
using namespace std;
typedef long long ll;
typedef pair<int, int> P;

int trans(int n, int b, char c[])
//(商+1)*除数+(余数-除数)
//=商*除数+除数+余数-除数
//=商*除数+余数=被除数
//因为我们是不断取余数倒序为转换结果,所以余数不能出现负数
//需要将商+1,余数-除数即可
// 因为余数(绝对值)一定小于除数,所以这样就可以将余数装换为正数
//重点:如果余数<0,那么:余数-=m;商++;懂就会,不懂就不会。
{
    int i = 0, k;
    while (n != 0) {
        k = n % b;
        n /= b;
        if (k < 0) {
            k -= b;
            n += 1;
        }
        if (k > 9)
            c[i] = char(k - 10 + 'A');
        else c[i] = char(k + '0');
        i++;
    }
    return i - 1;
}
//重点就是余数是负数就要转换
//余数大于9也要转换嘛
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int s;
    cin >> s;
    cout << s << "=";
    int cnt;
    char str[41];
    cin >> cnt;
    for (int i = trans(s, cnt, str); i >= 0; i--)
        cout << str[i];
    cout << "(base" << cnt << ')' << endl;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值