T1 立方数

题目

【题目描述】

作为XX战队的狂热粉丝,MdZzZZ看到了自己心仪的队伍在半决赛落败,顿时心灰意冷。看着自己手中的从黄牛那里抢来的天价总决赛门票,MdZzZZ觉得去鸟巢已经没有意义了,于是他决定去跳“水立方”。在他准备进“水立方”体育馆时,一位大妈拦住了他的去路,并产生了一下对话:

大妈:“年轻人我看你印堂发黑,恕我冒昧直言,此去一行怕是会有什么不测。”

MdZzZZ:“大妈别拦我,我要跳水立方发泄一下!”

大妈:“年轻人,做事要三思而后行,你知道这水立方最著名的是什么吗?”

MdZzZZ:“不知...”

大妈:“这水立方最有名的是‘立方数’!”

MdZzZZ:“哦?”

大妈:“别急,听我细细道来。‘立方数’就是,如果一个数可以被写作是一个正整数的3次方,则这个数就是立方数。例如1,8,27就是最小的3个立方数。”

MdZzZZ:“……”

大妈:“当然,想要在这水立方中来去自如,你需要知道‘立方差数’!”

大妈:“若一个数可以被写作是两个立方数的差,则这个数就是‘立方差数’,例如7(8-1),26(27-1),19(27-8)都是立方差数。如果你能够判断随便一个数是不是‘立方差数’,那么你就可以真正地在这一片小天地中当一条无忧无虑的小鱼...”

未等MdZzZZ反应过来,大妈以飘然远去,留下他一个人在那边细细思索。那么现在你的问题来了,你需要帮助MdZzZZ解决这个问题。

现在给定一个数P,MdZzZZ想要知道这个数是不是立方差数。

当然你有可能随机输出一些莫名其妙的东西,因此MdZzZZ有T次询问~

这个问题可能太难了…… 因此MdZzZZ规定P是个质数!

【输入格式】

第一行一个数T,表示有T组数据。

接下来T行,每行一个数P。

【输出格式】

输出T行,对于每个数如果是立方差数,输出“YES”,否则输出“NO”。

【输入样例】

5

2

3

5

7

11

【输出样例】

NO

NO

NO

YES

NO

【数据规模】

对于30%的数据p<=100。

对于60%的数据p<=10^6。

对于100%的数据p<=10^12,T<=100。

解析

嗯......题目很长,去掉废话,实际上就是要求质数p是不是立方差数(立方数即为a3-b3(a,b均为正整数,且a≠b)。

我们尝试化简一下a3-b3=p这个式子,可以得到(a-b)(a2+ab+b2)=p,因为p是质数,根据质数的定义(只有1和它本身是它的因数)可以得到,a-b与a2+ab+b2其中一个为1,

很显然a2+ab+b2不为1(因为a与b为互不相等的正整数),所以a-b=1,移项得a=b+1,带入a3-b3=p,得

(b+1)3-b3=p,即b3+3b2+3b+1-b3=p,化简并移项得3b2+3b+1-p=0,显然,这是一个一元二次方程,解这个方程可得,

b=(-3±sqrt(12p-3))/6(sqrt为求根号函数),由于b是正整数,所以如果-3±sqrt(12p-3)可以整除6的话,p就是立方差数。

由于p≤10^12,所以要记得开long long(本蒟蒻就是没开long long少了40分QAQ)。

Code

#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
long long read()
{
long long num=,w=;
char ch=getchar();
while(ch<''||ch>'')
{
if(ch=='-') w=-;
ch=getchar();
}
while(ch>=''&&ch<='')
{
num=(num<<)+(num<<)+ch-'';
ch=getchar();
}
return num*w;
}
int T;
long long p;
double a;
int main()
{
//freopen("cubicp.in","r",stdin);
//freopen("cubicp.out","w",stdout);
T=read();
while(T--)
{
p=read();
a=(sqrt(*p-)-)-(long long)(sqrt(*p-)-);
if(a==&&(long long)(sqrt(*p-)-)%==) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return ;
//fclose(stdin);
//fclose(stdout);
}

T2 二叉树

题目

【题目描述】

从前有一棵二叉树,我们用如下方式来表示这棵二叉树。

(1)如果一个节点没有儿子,我们用“0”来表示他。

(2)如果一个节点有一个儿子,我们对它的表示以“1”开头,后面接对它儿子的表示。

(3)如果一个节点有两个儿子,我们对它的表示以“2”开头,后面先接对它左儿子的表示,后接对它右儿子的表示。

KJDH十分贪玩,将这棵树染了色,KJDH又十分聪明,它染色又很有规则:每个节点不能和它的孩子有相同的颜色,如果一个节点有两个孩子,那么这两个孩子也不能有相同的颜色。

由于这个树年代久远了,所以我们看不清每个节点的颜色了,但我们知道KJDH只染了红黄白三种颜色。我们想知道这棵树最多和最少有多少个节点是白色的。

【输入格式】

输入文件只有一行,一个字符串,只有“0”,“1”,“2”组成,表示这棵树的结构。

【输出格式】

输出文件包含两个用空格隔开的数,分别表示白色节点的最多和最少数量。

【输入样例】

200

【输出样例】

1 1

【数据规模】

对于 20% 的数据,len<=10。

对于 50% 的数据,len<=2000

对于 100% 的数据,len<=500000。其中len为读入字符串的长度。

解析

不想说话,直接上大佬题解(手动滑稽):

Code

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN = ;
int f[MAXN][], g[MAXN][];
int n, m, i, j, len, k, lc[MAXN], rc[MAXN];
char s[MAXN];
inline int maketree(int x)
{
if (x > len) return ;
if (s[x] == '') return x;
if (s[x] == '') {lc[x] = ++n; return maketree(x + );}
if (s[x] == '') {lc[x] = ++n; int nex = maketree(x + ); rc[x] = ++n; return maketree(nex + );}
}
inline void dp(int now)
{
f[now][] = g[now][] = ;
if (lc[now] && !rc[now])
{
dp(lc[now]);
f[now][] += max(f[lc[now]][], f[lc[now]][]);
f[now][] += max(f[lc[now]][], f[lc[now]][]);
f[now][] += max(f[lc[now]][], f[lc[now]][]);
g[now][] += min(g[lc[now]][], g[lc[now]][]);
g[now][] += min(g[lc[now]][], g[lc[now]][]);
g[now][] += min(g[lc[now]][], g[lc[now]][]);
}
if (lc[now] && rc[now])
{
dp(lc[now]); dp(rc[now]);
f[now][] += max(f[lc[now]][] + f[rc[now]][], f[lc[now]][] + f[rc[now]][]);
f[now][] += max(f[lc[now]][] + f[rc[now]][], f[lc[now]][] + f[rc[now]][]);
f[now][] += max(f[lc[now]][] + f[rc[now]][], f[lc[now]][] + f[rc[now]][]);
g[now][] += min(g[lc[now]][] + g[rc[now]][], g[lc[now]][] + g[rc[now]][]);
g[now][] += min(g[lc[now]][] + g[rc[now]][], g[lc[now]][] + g[rc[now]][]);
g[now][] += min(g[lc[now]][] + g[rc[now]][], g[lc[now]][] + g[rc[now]][]);
}
}
int main()
{
//freopen("tree.in", "r", stdin);
//freopen("tree.out", "w", stdout);
scanf("%s", s + );
len = strlen(s + );
n = ;
maketree();
dp();
cout << max(f[][], max(f[][], f[][])) << " " << min(g[][], min(g[][], g[][])) << endl;
}

T3 Hanoi

题目

【题目描述】

众所周知, 汉诺塔是一个古老又经典的游戏. 这个游戏是这样的, 你有N个大小不同的盘子和3根柱子, 一开始所有盘子都叠放在第1根柱子上, 你需要把N个盘子全都移动到第3根柱子上, 每次都可以选择某根柱子最上面的盘子移动到另一根柱子上, 但是任何时候都必须保证没有一个盘子上面放了一个比它大的盘子. 求最少的移动步数.

这个问题太简单了, 乐于寻找挑战的你想要求出当有N个盘子, M个柱子且其他条件不变时, 把所有盘子从第1根柱子移动到第M根柱子的最少步数.

【输入格式】

一行两个整数分别代表题目中的N, M.

【输出格式】

一行一个整数代表答案.

【输入样例】

5 3

【输出样例】

31

【数据规模】

对于10%的数据, N <= 20, M = 3.

对于30%的数据, M = 3.

对于50%的数据, M <= 4.

对于100%的数据, N <= 63, 3 <= M <= N + 1;

解析

每天必不可少的DP题,令f[i][j]表示i个盘子j个柱子时的最少步数,怎样移动会是最少步数呢?

先把上面盘子移动到不是j的柱子上,再把剩下的盘子移动到j的柱子上,再把上面的盘子移动到j的柱子上。

递推式:f[i][j] = min(f[k][j] * 2 + f[i - k][j - 1])。

Code

#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
using namespace std;
int read()
{
int num=,w=;
char ch=getchar();
while(ch<''||ch>'')
{
if(ch=='-') w=-;
ch=getchar();
}
while(ch>=''&&ch<='')
{
num=(num<<)+(num<<)+ch-'';
ch=getchar();
}
return num*w;
}
int n,m;
long long f[][];
int main()
{
//freopen("hanoi.in","r",stdin);
//freopen("hanoi.out","w",stdout);
memset(f,0x7f7f7f7f,sizeof(f));
n=read(),m=read();
for(int i=;i<=m;i++) f[][i]=,f[][i]=;
for(int i=;i<=n;i++) f[i][]=*f[i-][]+;
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
for(int k=;k<i;k++) f[i][j]=min(f[i][j],*f[k][j]+f[i-k][j-]);
cout<<f[n][m];
return ;
//fclose(stdin);
//fclose(stdout);
}

T4 区间

题目

【题目描述】

有一个 n 个数的序列,一开始所有的数都是 0,每次可以将一个区间 [l,r](l ≤ r) 内的数 +1,求到达最 终状态的最少操作次数

【输入格式】

第一行包含一个正整数 n,表示序列的长度。

第二行包含 n 个不同的正整数 a1,a2,...,an,表示最终的状态。

【输出格式】

输出的第一行是一个正整数 m,表示最少的操作次数。 接下来 m 行每行两个正整数 li,ri,表示一次操作。你需要保证 1 ≤ li ≤ ri ≤ n。 保证最少次数 m ≤ 105,输出可以以任意顺序输出。

【输入样例】

2

8 8

【输出样例】

8

1 2

1 2

1 2

1 2

1 2

1 2

1 2

1 2

【数据规模】

解析

本蒟蒻只会O(nm)做法,直接上大佬题解吧:

Code

#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
int read()
{
int num=,w=;
char ch=getchar();
while(ch<''||ch>'')
{
if(ch=='-') w=-;
ch=getchar();
}
while(ch>=''&&ch<='')
{
num=(num<<)+(num<<)+ch-'';
ch=getchar();
}
return num*w;
}
int n,a[],d1[],d2[],temp;
void work(int l,int r,int lastmin)
{
for(int i=;i<=lastmin;i++) d1[++temp]=l,d2[temp]=r;
int nowmin=0x7f7f7f7f,ll=;
for(int i=l;i<=r;i++) a[i]-=lastmin;
for(int i=l;i<=r;i++)
if(a[i]==)
{
if(ll==) ll=i+;
else
{
if(ll>i-) continue;
for(int j=ll;j<=i-;j++) nowmin=min(nowmin,a[j]);
work(ll,i-,nowmin);
nowmin=0x7f7f7f7f,ll=i+;
}
}
else if(i==l) ll=l;
else if(i==r)
{
for(int j=ll;j<=r;j++) nowmin=min(nowmin,a[j]);
work(ll,r,nowmin);
}
}
int main()
{
//freopen("range.in","r",stdin);
//freopen("range.out","w",stdout);
n=read();
int nowmin=0x7f7f7f7f,ll=;
for(int i=;i<=n;i++) a[i]=read();
if(n==)
{
cout<<a[]<<endl;
for(int i=;i<=a[];i++) cout<<"1 1"<<endl;
return ;
}
work(,n,);
cout<<temp<<endl;
for(int i=;i<=temp;i++) cout<<d1[i]<<" "<<d2[i]<<endl;
return ;
//fclose(stdin);
//fclose(stdout);
}

O(nm)做法(69分)

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN = ;
int sum[MAXN << ], cnt[MAXN << ];
int n, m, i, j, k, l, r, ans, a[MAXN], tot;
inline int get()
{
char c;
while ((c = getchar()) < || c > );
int res = c - ;
while ((c = getchar()) >= && c <= )
res = res * + c - ;
return res;
}
inline void updata(int k)
{
sum[k] = min(sum[k << ], sum[k << | ]);
}
inline void putdown(int k)
{
if (cnt[k])
{
cnt[k << ] += cnt[k];
cnt[k << | ] += cnt[k];
sum[k << ] -= cnt[k];
sum[k << | ] -= cnt[k];
cnt[k] = ;
}
}
inline void change(int k, int p, int q, int l, int r)
{
if (p >= l && q <= r)
{
cnt[k] ++;
sum[k] --;
return;
}
putdown(k);
int mid = p + q >> ;
if (mid >= l) change(k << , p, mid, l, r);
if (mid < r) change(k << | , mid + , q, l, r);
updata(k);
}
inline int query(int k, int p, int q, int w)
{
if (p == q) return sum[k];
putdown(k);
int mid = p + q >> ;
if (mid >= w) return query(k << , p, mid, w);
else return query(k << | , mid + , q, w);
}
inline void maketree(int k, int p, int q)
{
if (p == q)
{
sum[k] = a[p];
return;
}
int mid = p + q >> ;
maketree(k << , p, mid);
maketree(k << | , mid + , q);
updata(k);
}
inline void find(int k, int p, int q, int l, int r)
{
int mid = p + q >> ;
if (tot) return;
putdown(k);
if (p == q) {if (!sum[k]) tot = p; return;}
if (p >= l && q <= r)
{
if (!sum[k << ]) find(k << , p, mid, l, r);
else if (!sum[k << | ]) find(k << | , mid + , q, l, r);
}
else
{
if (mid >= l) find(k << , p, mid, l, r);
if (mid < r) find(k << | , mid + , q, l, r);
}
}
int main()
{
//freopen("range.in", "r", stdin);
//freopen("range.out", "w", stdout);
cin >> n;
for(i = ; i <= n; i ++)
a[i] = get();
for(i = ; i <= n; i ++)
if (a[i] > a[i - ]) ans += a[i] - a[i - ];
cout << ans << endl;
maketree(, , n);
for(i = ; i <= n; i ++)
while (query(, , n, i))
{
tot = ;
find(, , n, i, n);
if (!tot) printf("%d %d\n", i, n), change(, , n, i, n);
else printf("%d %d\n", i, tot - ), change(, , n, i, tot - );
}
}

AC代码

长乐培训Day9的更多相关文章

  1. 长乐培训Day4

    T1 矩阵 题目 [题目描述] 从前有个 n×m 的矩阵,初始时每个位置均为 0.你需要依次执行 q 个操作,每个操作会指定一行或一列,然后将该行或该列的所有元素全部赋为一个相同的值. 输出操作完成后 ...

  2. 长乐培训Day8

    T1 远征 题目 [题目描述] 寒枫将军将要带领他的部队去圣雪山消灭那里的冰龙.部队分成了若干个小队,属于同一个小队的人兵种相同. 寒枫将军有着杰出的指挥能力,在战斗的时候,寒枫将军能够让所有相同兵种 ...

  3. 长乐培训Day7

    T1 删除 题目 [题目描述] 现在,我的手上有 n 个数字,分别是 a1,a2,a3,...,an. 我现在需要删除其中的 k 个数字.当然我不希望随随便便删除,我希望删除 k 数字之后,剩下的 n ...

  4. 长乐培训Day6

    T1 数列 题目 [题目描述] [输入格式] [输出格式] [输入样例] [输出样例] [数据规模] 如上所述. 解析 身为T1,居然比T4还难......让我怎么办......以下为巨佬题解: 我猜 ...

  5. 长乐培训Day5

    T1 圆圈舞蹈 题目 [题目描述] 熊大妈的奶牛在时针的带领下,围成了一个圈跳舞.由于没有严格的教育,奶牛们之间的间隔不一致. 奶牛想知道两只最远的奶牛到底隔了多远.奶牛A到B的距离为A顺时针走和逆时 ...

  6. 长乐培训Day3

    T1 奶牛晒衣服 题目 [题目描述] 在熊大妈英明的带领下,时针和他的同伴生下了许多牛宝宝.熊大妈决定给每个宝宝都穿上可爱的婴儿装.于是,为牛宝宝洗晒衣服就成了很不爽的事情. 圣人王担负起了这个重任. ...

  7. 长乐培训Day2

    T1 足球联赛 题目 [题目描述] 巴蜀中学新一季的足球联赛开幕了.足球联赛有n只球队参赛,每赛季,每只球队要与其他球队各赛两场,主客各一场,赢一场得3分,输一场不得分,平局两只队伍各得一分. 英勇无 ...

  8. 长乐培训Day1

    T1 魔法照片 题目 [题目描述] 如果你看过<哈利·波特>,你就会知道魔法世界里的照片是很神奇的.也许是因为小魔法师佳佳长的太帅,很多人都找他要那种神奇的魔法照片, 而且还都要佳佳和他的 ...

  9. 长乐国庆集训Day5

    T1 方阵 题目 [题目描述] 小澳最近迷上了考古,他发现秦始皇的兵马俑布局十分有特点,热爱钻研的小澳打算在电脑上还原这个伟大的布局. 他努力钻研,发现秦始皇布置兵马俑是有一定规律的.兵马俑阵总共有n ...

随机推荐

  1. jquery中清空

    jQuery("#map_bmmc").empty();   function qingkong(){         $("#form1").find(&qu ...

  2. DB2 sqlCode-668

    客户端调用命令 CALL SYSPROC.ADMIN_CMD('reorg table tablename')

  3. 2019全国大学生信息安全竞赛ciscn-writeup(4web)

    web1-JustSoso php伪协议获取源码 ?file=php://filter/read=convert.base64-encode/resource=index.php index.php ...

  4. Python操作MySQL数据库(步骤教程)

    我们经常需要将大量数据保存起来以备后续使用,数据库是一个很好的解决方案.在众多数据库中,MySQL数据库算是入门比较简单.语法比较简单,同时也比较实用的一个.在这篇博客中,将以MySQL数据库为例,介 ...

  5. IPFS系列 多节点搭建 二

    IPFS系列 多节点搭建 二 上一篇介绍了IPFS的分布式点对点超媒体传输协议的背景和安装介绍,本篇将继续指导搭建多节点的IPFS私有网络 文件服务.如果没还没开始搭建IPFS节点的小伙伴, 请戳此链 ...

  6. mkimage工具的用法

    1. mkimage都支持哪些压缩格式 none, gzip, bzip2等 2. 参考资料 这里

  7. Flutter 目录结构介绍、入口、自定义 Widget、MaterialApp 组件、Scaffold 组件

    Flutter 目录结构介绍 文件夹 作用 android android 平台相关代码 ios ios 平台相关代码 lib flutter 相关代码,我们主要编写的代 码就在这个文件夹 test ...

  8. 圣诞节雪花效果,pc端

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. 解决 Win10 系统新建文件夹后需手动刷新才能显示

    摘自:https://blog.csdn.net/weixin_44447687/article/details/100702968 1.点击开始菜单,选择“运行”功能,然后在运行打开框中输入 reg ...

  10. LeetCode_202. Happy Number

    202. Happy Number Easy Write an algorithm to determine if a number is "happy". A happy num ...