突然发现小米有 OJ!

然后发现居然刷题都能得奖品!而且都是水题

就开始板刷(一晚上 20 道题)

刷了 200 多个 OJ 币

然后发现:

也就是说我能兑换的都无库存

不能兑换的我不知道它有没有库存

算了我明天继续板刷,刷到 400 分看 T 恤有没有要是还没有我就打 12315 投诉

不过既然刷了就放出来吧

1. A + B

。。。

#include <bits/stdc++.h>

using namespace std;

int main()
{
    long long a, b;
    scanf("%lld%lld", &a, &b), printf("%lld\n", a + b);
    return 0;
}

2. 找出单独出现的数字

。。。

#include <bits/stdc++.h>

using namespace std;

bool cnt[256];

int main(int argc, char const* argv[])
{
    int a;
    while (~scanf("%d", &a)) cnt[a] ^= 1;
    for (int i = 0; i < 256; i += 1) if (cnt[i]) printf("%d\n", i), exit(0);
    return 0;
}

3. 大数相减

。。。

#include <bits/stdc++.h>

#define NS (10000)

using namespace std;

char str[NS];

struct bigInt
{
    int d[NS], n;
    int& operator [] (const int a) {return d[a];}
    bool input()
    {
        char c; n = 0;
        while (c = getchar(), !isdigit(c));
        while (isdigit(c)) str[n++] = c, c = getchar();
        reverse(str, str + n), n--;
        for (int i = 0; i <= n; i += 1) d[i] = str[i] - '0';
    }
    void print()
    {
        for (int i = n; i >= 0; i -= 1) putchar(d[i] + '0');
        putchar(10);
    }
    void operator -= (bigInt &oth)
    {
        for (int i = 0; i <= oth.n; i += 1) d[i] -= oth[i];
        for (int i = 0; i <= n; i += 1)
            while (d[i] < 0) d[i] += 10, d[i + 1]--;
        while (!d[n]) n--;
    }
} A, B;

int main(int argc, char const* argv[])
{
    A.input(), B.input(), A -= B, A.print();
    return 0;
}

4. 最长连续数列

说好的 $O(n)$呢?

实际上是对 Java/Python 说的吧

(但是 Java 排序也能过。。。)

#include <bits/stdc++.h>

#define NS (500005)

using namespace std;

int n, l, A[NS];

char buff[NS << 1];

void input()
{
    scanf("%s", buff), l = strlen(buff);
    int i = 0;
    while (i < l)
    {
        while (!isdigit(buff[i]) && i < l) i++;
        if (i == l) return;
        n++;
        while (isdigit(buff[i])) A[n] = A[n] * 10 + buff[i++] - '0';
    }
}

int main(int argc, char const* argv[])
{
    input(), sort(A + 1, A + 1 + n);
    int ans = 1, cnt = 1;
    for (int i = 2; i <= n; i += 1)
        if (A[i] == A[i - 1] + 1) cnt++;
        else ans = max(ans, cnt), cnt = 1;
    printf("%d\n", max(ans, cnt));
    return 0;
}

5. 找出旋转有序数列的中间值

就搞不懂了为什么一定要用这么制杖的读入方式

而且和旋转有半毛钱关系吗?

#include <bits/stdc++.h>

#define NS (500005)

using namespace std;

int n, l, A[NS];

char buff[NS << 1];

void input()
{
    scanf("%s", buff), l = strlen(buff);
    int i = 0; bool flag;
    while (i < l)
    {
        flag = 0;
        while (!isdigit(buff[i]) && i < l)
        {
            if (buff[i] == '-') flag = 1;
            i++;
        }
        if (i == l) return;
        n++;
        while (isdigit(buff[i])) A[n] = A[n] * 10 + buff[i++] - '0';
        if (flag) A[n] = -A[n];
    }
}

int main(int argc, char const* argv[])
{
    input(), nth_element(A + 1, A + ((n + 1) >> 1), A + 1 + n);
    printf("%d\n", A[(n + 1) >> 1]);
    return 0;
}

6. 交叉队列

又不告诉数据范围。。。

实际上 $O(n ^ 2)$Dp 就行了

#include <bits/stdc++.h>

#define NS (1000)

using namespace std;

char buff[NS], s1[NS], s2[NS], s3[NS];

int l1, l2, l3;

void input(char (&a)[NS], int &l)
{
    char c; l = 0;
    while (c = getchar(), !isalpha(c));
    while (isalpha(c)) a[l++] = c, c = getchar();
}

int f[NS][NS];

bool Dfs(int a, int b)
{
    if (f[a][b]) return f[a][b] - 1;
    f[a][b] = 1;
    if (a > 0 && s3[a + b - 1] == s1[a - 1] && Dfs(a - 1, b)) f[a][b] = 2;
    else if (b > 0 && s3[a + b - 1] == s2[b - 1] && Dfs(a, b - 1)) f[a][b] = 2;
    return f[a][b] - 1;
}

int main(int argc, char const* argv[])
{
    input(s1, l1), input(s2, l2), input(s3, l3);
    if (l1 + l2 != l3) puts("false"), exit(0);
    f[0][0] = 2;
    if (Dfs(l1, l2)) puts("true");
    else puts("false");
    return 0;
}

7. 第一个缺失正数

。。。

#include <bits/stdc++.h>

#define NS (500000)

using namespace std;

int n, l, A[NS];

char buff[NS];

void input()
{
    scanf("%s", buff), l = strlen(buff);
    int i = 0; bool flag;
    while (i < l)
    {
        flag = 0;
        while (!isdigit(buff[i]) && i < l)
        {
            if (buff[i] == '-') flag = 1;
            i++;
        }
        if (i == l) return;
        n++;
        while (isdigit(buff[i])) A[n] = A[n] * 10 + buff[i++] - '0';
        if (flag) A[n] = -A[n];
    }
}

int main(int argc, char const* argv[])
{
    input(), sort(A + 1, A + 1 + n);
    int ans = 1;
    for (int i = 1; i <= n; i += 1) if (A[i] == ans) ans++;
    printf("%d\n", ans);
    return 0;
}

8. 最少交换次数

老套路树状数组模拟

只是没有数据范围

#include <bits/stdc++.h>

#define NS (500000)
#define lowbit(a) ((a) & (-(a)))

using namespace std;

typedef long long LL;

int n, l, A[NS], h[NS], hs, at[NS];

char buff[NS];

void input()
{
    scanf("%s", buff), l = strlen(buff);
    int i = 0; bool flag;
    while (i < l)
    {
        flag = 0;
        while (!isdigit(buff[i]) && i < l)
        {
            if (buff[i] == '-') flag = 1;
            i++;
        }
        if (i == l) return;
        n++;
        while (isdigit(buff[i])) A[n] = A[n] * 10 + buff[i++] - '0';
        if (flag) A[n] = -A[n];
    }
}

int t[NS];

void add(int x, int d)
{
    while (x <= n) t[x] += d, x += lowbit(x);
}

int sum(int x)
{
    int res = 0;
    while (x) res += t[x], x -= lowbit(x);
    return res;
}

void preWork()
{
    memmove(h + 1, A + 1, sizeof(int) * n), sort(h + 1, h + 1 + n);
    h[0] = INT_MIN;
    for (int i = 1; i <= n; i += 1)
        if (h[i] != h[i - 1]) h[++hs] = h[i];
    for (int i = 1; i <= n; i += 1)
    {
        A[i] = lower_bound(h + 1, h + 1 + hs, A[i]) - h;
        at[A[i]] = i, add(i, A[i] - i), add(i + 1, i - A[i]);
    }
}

int main(int argc, char const* argv[])
{
    input(), preWork();
    LL ans = 0;
    for (int i = 1; i <= n; i += 1)
    {
        ans += abs(sum(at[i]));
        add(1, -1), add(at[i], 1);
    }
    printf("%lld\n", ans);
    return 0;
}

9. 移除 K 位得到最小值

贪心,还挺有意思的

如果当前某一位比它后面一位大就删除它

当然被删除的这一位越靠前越好

#include <bits/stdc++.h>

using namespace std;

char str[20];

int l, k;

void scan()
{
    int i = 0;
    while (i < l - 1 && str[i] <= str[i + 1]) i++;
    for (int j = i; j < l - 1; j += 1) str[j] = str[j + 1];
    l--, str[l] = 0;
}

int main(int argc, char const* argv[])
{
    scanf("%s%d", str, &k), l = strlen(str);
    for (int i = 1; i <= k; i += 1) scan();
    int i = 0;
    while (str[i] == '0') i++;
    if (i == l) puts("0");
    else
    {
        while (i < l) putchar(str[i++]);
        putchar(10);
    }
    return 0;
}

10. 爬楼梯

斐波那契甚至不取模,都懒得滚动了

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

template<typename _Tp> inline void IN(_Tp& dig)
{
    char c; bool flag = 0; dig = 0;
    while (c = getchar(), !isdigit(c)) if (c == '-') flag = 1;
    while (isdigit(c)) dig = dig * 10 + c - '0', c = getchar();
    if (flag) dig = -dig;
}

int n;

LL f[1000];

int main(int argc, char const* argv[])
{
    IN(n), f[0] = 1, f[1] = 1;
    for (int i = 1; i <= n; i += 1) f[i] = f[i - 1] + f[i - 2];
    printf("%lld\n", f[n]);
    return 0;
}

11. 构建短字符串

亮点在样例输入中

a b
aa ab
aa aab
uak areuok

。。。

#include <bits/stdc++.h>

#define NS (500000)

using namespace std;

char s1[NS], s2[NS];

int l1, l2, cnt[128];

int main(int argc, char const* argv[])
{
    scanf("%s%s", s1, s2), l1 = strlen(s1), l2 = strlen(s2);
    for (int i = 0; i < l2; i += 1) cnt[s2[i]]++;
    for (int i = 0; i < l1; i += 1)
        if (!cnt[s1[i]]) puts("false"), exit(0);
        else cnt[s1[i]]--;
    puts("true");
    return 0;
}

12. 找出可能的合的组合

Dp 真好玩

#include <bits/stdc++.h>

#define NS (500000)

using namespace std;

int n, l, A[NS], m;

char buff[NS << 1];

void input()
{
    scanf("%s", buff), l = strlen(buff);
    int i = 0; bool flag;
    while (i < l)
    {
        flag = 0;
        while (!isdigit(buff[i]) && i < l)
        {
            if (buff[i] == '-') flag = 1;
            i++;
        }
        if (i == l) return;
        n++;
        while (isdigit(buff[i])) A[n] = A[n] * 10 + buff[i++] - '0';
        if (flag) A[n] = -A[n];
    }
}

int f[NS];

int Dfs(int a)
{
    if (f[a] != -1) return f[a];
    f[a] = 0;
    for (int i = 1; i <= n; i += 1)
        if (a >= A[i]) f[a] += Dfs(a - A[i]);
    return f[a];
}

int main(int argc, char const* argv[])
{
    input(), scanf("%d", &m);
    memset(f, -1, sizeof(f)), f[0] = 1;
    printf("%d\n", Dfs(m));
    return 0;
}

13. 出现频率最高的前 K 个元素

。。。

#include <bits/stdc++.h>

#define NS (500000)
#define FIR first
#define SEC second

using namespace std;

typedef pair<int ,int> PII;

int n, l, A[NS];

char buff[NS << 1];

void input()
{
    scanf("%s", buff), l = strlen(buff);
    int i = 0; bool flag;
    while (i < l)
    {
        flag = 0;
        while (!isdigit(buff[i]) && i < l)
        {
            if (buff[i] == '-') flag = 1;
            i++;
        }
        if (i == l) return;
        n++;
        while (isdigit(buff[i])) A[n] = A[n] * 10 + buff[i++] - '0';
        if (flag) A[n] = -A[n];
    }
}

int cnt;

PII P[NS];

bool cmp(PII a, PII b)
{
    if (a.FIR == b.FIR) return a.SEC < b.SEC;
    return a.FIR > b.FIR;
}

int main(int argc, char const* argv[])
{
    input(), sort(A + 1, A + 1 + n), A[0] = INT_MIN;
    for (int i = 1; i <= n; i += 1)
        if (A[i] != A[i - 1]) P[++cnt].FIR = 1, P[cnt].SEC = A[i];
        else P[cnt].FIR++;
    int k; scanf("%d", &k);
    sort(P + 1, P + 1 + cnt, cmp), printf("%d", P[1].SEC);
    for (int i = 2; i <= k; i += 1) printf(",%d", P[i].SEC);
    putchar(10);
    return 0;
}

14. 在一个有序的经过旋转的数组里查找一个数

。。。

#include <bits/stdc++.h>

#define NS (500005)

using namespace std;

int n, l, A[NS], q;

char buff[NS << 1];

void input()
{
    scanf("%s", buff), l = strlen(buff);
    int i = 0; bool flag;
    while (i < l)
    {
        flag = 0;
        while (!isdigit(buff[i]) && i < l)
        {
            if (buff[i] == '-') flag = 1;
            i++;
        }
        if (i == l) return;
        n++;
        while (isdigit(buff[i])) A[n] = A[n] * 10 + buff[i++] - '0';
        if (flag) A[n] = -A[n];
    }
}

int main(int argc, char const* argv[])
{
    input(), scanf("%d", &q);
    for (int i = 1; i <= n; i += 1)
        if (A[i] == q) printf("%d\n", i - 1), exit(0);
    puts("-1");
    return 0;
}

15. 和为零的三元组

map 瞎搞一通

#include <bits/stdc++.h>

#define NS (500005)

using namespace std;

int n, l, A[NS];

char buff[NS << 1];

void input()
{
    scanf("%s", buff), l = strlen(buff);
    int i = 0; bool flag;
    while (i < l)
    {
        flag = 0;
        while (!isdigit(buff[i]) && i < l)
        {
            if (buff[i] == '-') flag = 1;
            i++;
        }
        if (i == l) return;
        n++;
        while (isdigit(buff[i])) A[n] = A[n] * 10 + buff[i++] - '0';
        if (flag) A[n] = -A[n];
    }
}

typedef pair<int, int> PII;
typedef pair<int, PII> PIP;

map<int, int> mp;
map<PIP, bool> book;

int main(int argc, char const* argv[])
{
    input(), sort(A + 1, A + 1 + n);
    for (int i = 1; i <= n; i += 1) mp[-A[i]] = i;
    int ans = 0;
    for (int i = 1; i <= n; i += 1)
        for (int j = 1; j <= n; j += 1)
            if (i < j && mp[A[i] + A[j]] && j < mp[A[i] + A[j]])
            {
                if (book[PIP(A[i], PII(A[j], A[mp[A[i] + A[j]]]))])
                    continue;
                ans++;
                book[PIP(A[i], PII(A[j], A[mp[A[i] + A[j]]]))] = 1;
            }
    printf("%d\n", ans);
    return 0;
}

16. 四则运算

。。。后缀表达式

直接贴的以前的代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <ctype.h>

int ints[10000];
int intt;//ints 的 top 
char chas[10000];
int chat;//chas 的 top 
int i=0, ii=1;
char c;
char get[10000];//输入的中缀表达式 
char get2[10000];//计算得出的后缀表达式 

void intpush(int x)//整型栈压栈 
{
    intt++; ints[intt]=x;
}
void chapush(char x)//字符型栈压栈 
{
    chat++; chas[chat]=x;
}
int intpop()//整型栈弹出 
{
    intt--; return ints[intt+1];
}
char chapop()//字符型栈弹出 
{
    chat--; return chas[chat+1];
}
void intadd(int x)//整型栈栈顶元素加入新的个位数字 
{
    ints[intt]*=10; ints[intt]+=x;
}

int find()//get2 加入操作符 
{
    c=chapop();
    get2[ii]=' ';
    get2[ii+1]=c;
    ii+=2;
    if(chat==0) return 0;
    return 1;
}

int main()
{
    intt=0; chat=0;
    fgets(get, 1000000, stdin);
    int lengets=strlen(get);
    for(i=0;i<=lengets-1;i++)//逐个读取输入的中缀表达式 
    {
        if (isdigit(get[i]))//当 get[i] 为数字时 
        {
            get2[ii]=get[i];
            ii++;
        }
        else
        {
            if(get[i]=='(')chapush('(');
            if(get[i]=='^')chapush('^');
            if(get[i]==')')
            {
                c=chapop();
                while(c!='(')
                {
                    get2[ii]=' ';
                    get2[ii+1]=c;
                    ii+=2;
                    c=chapop();
                }
            }
            if(get[i]=='+')
            {
                while(chas[chat]=='+'||chas[chat]=='-'||chas[chat]=='*'||chas[chat]=='/'||chas[chat]=='^')
                {
                    if(find()==0)break;
                }
                chapush('+');
            }
            if(get[i]=='-')
            {
                while(chas[chat]=='+'||chas[chat]=='-'||chas[chat]=='*'||chas[chat]=='/'||chas[chat]=='^')
                {
                    if(find()==0)break;
                }
                chapush('-');
            }
            if(get[i]=='*')
            {
                while(chas[chat]=='*'||chas[chat]=='/'||chas[chat]=='^')
                {
                    if(find()==0)break;
                }
                chapush('*');
            }
            if(get[i]=='/')
            {
                while(chas[chat]=='*'||chas[chat]=='/'||chas[chat]=='^')
                {
                    if(find()==0)break;
                }
                chapush('/');
            }
            get2[ii]=' ';
            ii++;
        }

    }
    while(chat>0)//输出栈内剩余的操作符 
    {
        int c=chapop();
        get2[ii]=' ';
        get2[ii+1]=c;
        ii+=2;
    }
    get2[ii]='@';//加入结束符 
    i=1;
    while(get2[i]!='@')//当看到结束符停止计算 
    {
        if(get2[i]=='+'||get2[i]=='-'||get2[i]=='*'||get2[i]=='/'||get2[i]=='^')
        {
            int a=intpop();int b=intpop();int c;
            if(get2[i]=='+') c=a+b;
            if(get2[i]=='-') c=b-a;
            if(get2[i]=='*') c=a*b;
            if(get2[i]=='/')
            {
                if (!a)puts("err"),exit(0);
                c=b/a;
            }
            if(get2[i]=='^') c=pow(b,a);
            intpush(c);
        }
        else
        {
            if(get2[i]!=' ')
            {
                intpush(get2[i]-48);
                ii=1;
                while(get2[i+ii]!=' ')
                {
                    intadd(get2[i+ii]-48);
                    ii++;
                }
                i+=ii-1;
            }
        }
        i++;
    }
    printf("%d\n",ints[1]);
    return 0;
}

17. 小写数字转大写数字

这题就是恶心人的,真没意思

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

template<typename _Tp> inline void IN(_Tp& dig)
{
    char c; bool flag = 0; dig = 0;
    while (c = getchar(), !isdigit(c)) if (c == '-') flag = 1;
    while (isdigit(c)) dig = dig * 10 + c - '0', c = getchar();
    if (flag) dig = -dig;
}

char *QAQ[] = {"", "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿", "拾", "佰"};
char *OvO[] = {"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"};

LL n;

bool zero, vis;

void Orz(LL a, int b)
{
    if (a >= 10) Orz(a / 10, b + 1);
    if (b % 4 == 3) zero = 0, vis = 0;
    if (a % 10 == 0)
    {
        zero = 1;
        if (b % 4 == 0 && vis) printf("%s", QAQ[b]);
        return;
    }
    if (zero) printf("零"), zero = 0;
    printf("%s%s", OvO[a % 10], QAQ[b]), zero = 0, vis = 1;
}

int main(int argc, char const* argv[])
{
    IN(n);
    if (!n) puts("零元整"), exit(0);
    Orz(n, 0), puts("元整");
    return 0;
}

18. 帮小学生排队

如果从高到低排序,每次把当前的插入,那低的一定不会影响高的 “前面比他高的人数”

相同高度的 “前面比他高的人数” 小的站前面

$O(n ^ 2)$的

#include <bits/stdc++.h>

#define NS (5000)

#define FIR first
#define SEC second

using namespace std;

typedef pair<int, int> PII;

template<typename _Tp> inline void IN(_Tp& dig)
{
    char c; bool flag = 0; dig = 0;
    while (c = getchar(), !isdigit(c)) if (c == '-') flag = 1;
    while (isdigit(c)) dig = dig * 10 + c - '0', c = getchar();
    if (flag) dig = -dig;
}

bool cmp(PII a, PII b)
{
    if (a.FIR == b.FIR) return a.SEC < b.SEC;
    return a.FIR > b.FIR;
}

int n, id[NS];

PII P[NS];

void insert(int x, int d)
{
    memmove(id + x + 1, id + x, sizeof(int) * (n - x));
    id[x] = d;
}

int main(int argc, char const* argv[])
{
    IN(n);
    for (int i = 1; i <= n; i += 1) IN(P[i].FIR), IN(P[i].SEC);
    sort(P + 1, P + 1 + n, cmp);
    for (int i = 1; i <= n; i += 1) insert(P[i].SEC, i);
    for (int i = 0; i < n; i += 1)
        printf("%d %d ", P[id[i]].FIR, P[id[i]].SEC);
    putchar(10);
    return 0;
}

19. 大数的加法运算与大小判断

python 真好用

(第一次写 python)

def solution(line):
    if '<' in line:
        a, b = line.strip().split('<')
        if int(a) < int(b):
            return 'Y'
        else:
            return 'N'
    if '>' in line:
        a, b = line.strip().split('>')
        if int(a) > int(b):
            return 'Y'
        else:
            return 'N'
    a, b = line.strip().split('+')
    return str(int(a) + int(b))

20. 有多少个等差数列?

枚举序列结束为止与公差,Dp 即可

#include <bits/stdc++.h>

#define NS (205)

using namespace std;

int n, l, A[NS];

char buff[NS << 1];

void input()
{
    fgets(buff, NS, stdin), l = strlen(buff);
    int i = 0; bool flag;
    while (i < l)
    {
        flag = 0;
        while (!isdigit(buff[i]) && i < l)
        {
            if (buff[i] == '-') flag = 1;
            i++;
        }
        if (i == l) return;
        n++;
        while (isdigit(buff[i])) A[n] = A[n] * 10 + buff[i++] - '0';
        if (flag) A[n] = -A[n];
    }
}

int f[NS][405], ans;

int main(int argc, char const* argv[])
{
    input();
    for (int i = 1; i <= n; i += 1)
        for (int j = 1; j < i; j += 1)
            f[i][A[i] - A[j] + 200]++;
    for (int i = 1; i <= n; i += 1)
    {
        for (int j = 1; j < i; j += 1)
            f[i][A[i] - A[j] + 200] += f[j][A[i] - A[j] + 200];
        for (int j = 0; j <= 400; j += 1) ans += f[i][j];
    }
    printf("%d\n", ans);
    return 0;
}

21. 按序组合成最大的数

$n ^ 3$ DP

怕爆精度直接写 (chao) 的 python

def solution(line):
    buff = line.split(' ')
    a = buff[0].split(',')
    b = buff[1].split(',')
    k = int(buff[2])
    f = []
    l1 = len(a)
    l2 = len(b)
    for i in range(l1):
        a[i] = int(a[i])
    for i in range(l2):
        b[i] = int(b[i])
    for i in range(l1 + 1):
        f.append([])
        for j in range(l2 + 1):
            f[i].append([])
            for k in range(k + 1):
                f[i][j].append(0)
    for i in range(1, l1 + 1):
        f[i][0][1] = a[i - 1]
    for i in range(1, l2 + 1):
        f[0][i][1] = b[i - 1]
    for i in range(l1 + 1):
        for j in range(l2 + 1):
            for k in range(1, k + 1):
                if i > 0:
                    f[i][j][k] = max(f[i][j][k], max(f[i - 1][j][k], f[i - 1][j][k - 1] * 10 + a[i - 1]))
                if j > 0:
                    f[i][j][k] = max(f[i][j][k], max(f[i][j - 1][k], f[i][j - 1][k - 1] * 10 + b[j - 1]))
    return f[l1][l2][k]

22. 找到第 N 个数字

等差数列,解下方程就行了

(题目说的 20 位是不存在的,用 long long 就行了)

#include <bits/stdc++.h>

typedef long long LL;

using namespace std;

LL n;

char s[] = "1234567898765432";

int main(int argc, char const* argv[])
{
    scanf("%lld", &n);
    LL x = ceil((sqrt((double)1 + (n << 3)) - 1) / 2) - 1;
    n -= (x * x + x) / 2 + 1;
    putchar(s[n % 16]);
    return 0;
}

23. 找到第 N 个数字 II

这次 $n$比较小,懒得二分直接 $\sqrt n$找

然后找所在位置就行了

#include <bits/stdc++.h>

typedef long long LL;

using namespace std;

LL n, l = 1, k = 1;

int main(int argc, char const* argv[])
{
    scanf("%lld", &n);
    int i = 1, d = 1, p = 10;
    while ("orz litble")
    {
        if (n <= l) break;
        n -= l;
        if ((++i) % p == 0) p *= 10, d++;
        l += d;
    }
    l = 1;
    while ("Orz litble")
    {
        LL p = l * (k * 10 - k);
        if (n <= p)
        {
            LL x = ceil((double)n / l) + k - 1;
            n = ceil((double)n / l) * l - n;
            while (n) x /= 10, n--;
            printf("%lld\n", x % 10);
            break;
        }
        n -= p, l++, k *= 10;
    }
    return 0;
}

24. 海盗分赃

数据这么大咋整。。。

于是就写了模拟退火,居然 AC 了=。=

但是那些写背包的也 AC 了,数据太水了吧

#include <bits/stdc++.h>

#define NS (105)
#define Rand() ((double)rand() / RAND_MAX)
#define ABS(a) ((a) < 0 ? (-(a)) : a)

using namespace std;

int n, l, A[NS];

char buff[NS << 1];

void input()
{
    scanf("%s", buff), l = strlen(buff);
    int i = 0; bool flag;
    while (i < l)
    {
        flag = 0;
        while (!isdigit(buff[i]) && i < l)
        {
            if (buff[i] == '-') flag = 1;
            i++;
        }
        if (i == l) return;
        n++;
        while (isdigit(buff[i])) A[n] = A[n] * 10 + buff[i++] - '0';
        if (flag) A[n] = -A[n];
    }
}

int sum, f, vis[NS], ans = INT_MAX;

int main(int argc, char const* argv[])
{
    srand(19260817), input();
    for (int i = 1; i <= n; i += 1) sum += A[i];
    if (sum & 1) puts("false"), exit(0);
    f = sum, sum >>= 1, memset(vis + 1, -1, sizeof(int) * n);
    double T = 10000;
    while (T > 1e-6)
    {
        for (int C = 1; C <= 50; C += 1)
        {
            int a = rand() % n + 1;
            int dt = ABS(f - sum) - ABS(f + vis[a] * A[a] - sum);
            if (dt > 0 || exp((double)dt / T) > Rand())
                f += vis[a] * A[a], vis[a] *= -1;
            ans = min(ans, ABS(f - sum));
        }
        T *= 0.98;
    }
    if (!ans) puts("true");
    else puts("false");
    return 0;
}

28. 组长偏头痛

二分答案

#include <bits/stdc++.h>

#define NS (100005)

using namespace std;

int k, n, l, A[NS];

char buff[NS << 1];

void input()
{
    scanf("%s", buff), l = strlen(buff);
    int i = 0; bool flag;
    while (i < l)
    {
        flag = 0;
        while (!isdigit(buff[i]) && i < l)
        {
            if (buff[i] == '-') flag = 1;
            i++;
        }
        if (i == l) return;
        n++;
        while (isdigit(buff[i])) A[n] = A[n] * 10 + buff[i++] - '0';
        if (flag) A[n] = -A[n];
    }
}

int main(int argc, char const* argv[])
{
    scanf("%d", &k), input();
    int l = 0, r = 0, mid;
    for (int i = 1; i <= n; i += 1) l = max(l, A[i]), r += A[i];
    while (l < r)
    {
        mid = (l + r) >> 1;
        bool flag = 1;
        for (int i = 1, rem = mid, x = k - 1; i <= n; i += 1)
        {
            if (A[i] > rem)
            {
                if (!x) { flag = 0; break; }
                x--, rem = mid;
            }
            rem -= A[i];
        }
        if (flag) r = mid;
        else l = mid + 1;
    }
    printf("%d\n", l);
    return 0;
}

32. 判断是否为连乘数字串

暴搜

#include <bits/stdc++.h>

#define NS (105)

using namespace std;

typedef long long LL;

int n;

char s[NS];

bool Dfs(int a, LL x, LL y, LL z, int c)
{
    if (a > n) return (c >= 3 && !z);
    z = z * 10 + s[a] - '0';
    if (z > 1e9) return 0;
    bool res = 0;
    if (z == x * y || x == -1) res |= Dfs(a + 1, y, z, 0, c + 1);
    return (res | Dfs(a + 1, x, y, z, c));
}

int main(int argc, char const* argv[])
{
    scanf("%s", s + 1), n = strlen(s + 1);
    puts(Dfs(1, -1, -1, 0, 0) ? "true" : "false");
    return 0;
}

(未完待续)

分类: 文章

Remmina

No puzzle that couldn't be solved.

5 条评论

attack204 · 2019年2月22日 5:46 下午

这个 OJ 的兑换是定期开放的。能换的时候会在 OJ 群里说 (大概一个月一次吧,然后每次只有 1min 左右抢的时间。。

    Remmina · 2019年2月22日 6:49 下午

    1 min???

    报警了

    有空的时候写一个自动检测是否有货的脚本吧

    有货就蜂鸣器报警

    _(:зゝ∠)_

Xeonacid · 2019年1月26日 7:42 下午

哇这个鬼畜读入方式您能做得下去 orz,窝做不下去了想打人(

    Remmina · 2019年1月26日 9:15 下午

    QwQ 似乎鬼畜的输入方式都一样,写一个 input 复制就行辣
    (另外我似乎已经通过打比赛发小财了)

      Xeonacid · 2019年1月27日 10:42 上午

      xmsl.jpg

发表评论

电子邮件地址不会被公开。 必填项已用*标注