目录
前言
今天是一只emo羊🐏,没有听懂学长讲的东西😔,昨天遗留的结构体C-C原来写的代码虽然找到了那个错误,运行结果对了,但交了之后时间又超限了。算了,这些都不重要,还是有学到的东西的,一起来看看吧。
一、跳棋大师
题目:作为一代跳棋大师,你的职业地位受到了来自人工智能的挑战。
最近,有公司宣布他们研发出了最新的跳棋人工智能“深黑”。但是它现在还只能挑战最简单的跳棋局面。
为了使人工智能方便,我们使用以下的跳棋规则。
1.跳棋由且仅由一列长串棋盘构成,假设长度为n,每个位置放置了一个障碍物或者为空,开头和结尾位置只能为空
2.跳棋可以利用障碍物来跳跃,跳跃指的是跳棋可以利用前方的一个棋子来跳跃任意正数距离,只能落在空上,不能落在障碍物上,一次跳跃只能跃过一个障碍物。
比如“棋空空空物空空空” -> “空空空空物棋空空” 合法
“棋空空空物空空空” -> “空空空空物空空棋” 合法
“棋空空空物物空空” -> “空空空空物物空棋” 违法 因为跃过了两个障碍物
3.我们称一个棋盘合法指的是假设你有一颗跳棋在开头位置,你可以通过规则2规定的方式跳到结尾位置
现在问题是给你一个n(1<=n<=1e5),问你一共可以构造出多少种不同的合法棋盘来考验“深黑”的性能。
棋盘不同指的是存在某个位置不同(障碍物或者空)。
因为答案种数可能很多,所以答案对(1000000007)取膜。
输入:
输入只有一个数n,代表棋盘规模
(1<=n<=1e5)
输出:
输出一个数代表一共可以构造出多少种不同的合法棋盘,因为答案种数可能很多,所以答案对(1000000007)取膜。
样例输入 Copy
4
样例输出 Copy
2
提示
“空物空空”,“空空物空” 两种是不同方案
思路:
这个题目完全就是规律题,所以要自己动手画一画偶,这个找规律的过程就交给你自己了,不要偷懒啊!!!如果你画不出来,就好好去看看题🐶🐶🐶,不过还是给你看看找出来的规律吧,不过得自己找到了规律才能理解。
规律:
代码实现:
#include<stdio.h>
long long a[100006]={1,0,1,2};
int main()
{
long long n,i;
scanf("%lld",&n);
for(i=4;i<n;i++)
{
a[i]=a[i-1]+a[i-2]+1;//找规律
a[i]%=1000000007;
}
printf("%lld",a[n-1]);
return 0;
}
二、结构体c-c
题目:
“今年暑假不AC?”
“是的。”
“那你干什么呢?”
“看世界杯呀,笨蛋!”
“@#$%^&*%...”
确实如此,世界杯来了,球迷的节日也来了,估计很多ACMer也会抛开电脑,奔向电视了。
作为球迷,一定想看尽量多的完整的比赛,当然,作为新时代的好青年,你一定还会看一些其它的节目,比如新闻联播(永远不要忘记关心国家大事)、非常6+7、超级女生,以及王小丫的《开心辞典》等等,假设你已经知道了所有你喜欢看的电视节目的转播时间表,你会合理安排吗?(目标是能看尽量多的完整节目)
输入:
输入数据包含多个测试实例,每个测试实例的第一行只有一个整数n(n<=100),表示你喜欢看的节目的总数,然后是n行数据,每行包括两个数据Ti_s,Ti_e (1<=i<=n),分别表示第i个节目的开始和结束时间,为了简化问题,每个时间都用一个正整数表示。n=0表示输入结束,不做处理。
输出:
对于每个测试实例,输出能完整看到的电视节目的个数,每个测试实例的输出占一行。
Sample Input
12 1 3 3 4 0 7 3 8 15 19 15 20 10 15 8 18 6 12 5 10 4 14 2 9 0Sample Output
5
思路:
1、多组输入
2、(1)根据每个节目开始时间对结构体进行从大到小排序。
(2)记录a[0]开始时间;与下一个结束时间比较,下一个结束时间<=则cnt++;以此类推
代码实现:
(1)版本1(可能时间会超限,但我觉得思路很清晰)
#include<stdio.h>
struct time{
int t1;
int t2;
};
int main()
{
int n;
while(scanf("%d",&n)!=EOF)//多组输入
{
if(n==0)
break; //输入0,则不处理
struct time a[1000],temp;
for(int i=0;i<n;i++)
{
scanf("%d%d",&a[i].t1,&a[i].t2);//输入n组t1,t2
}
for(int j=0;j<n-1;j++) //冒泡排序
for(int i=0;i<n-1-j;i++)
{
if(a[i].t1<a[i+1].t1)
{
temp=a[i];
a[i]=a[i+1];
a[i+1]=temp;//从大到小排序每个节目t1
}
else if(a[i].t1==a[i+1].t1&&a[i].t2>a[i+1].t2)
{
temp=a[i];
a[i]=a[i+1];
a[i+1]=temp;//t1相同的按t2从小到大排
}
}
int cnt=1,t=0;
for(int i=t;i<n;i=t)
for(int j=i+1;j<n;j++)
{
if(a[j].t2<=a[i].t1)
{
cnt++;
t=j;
break;
}
else if(j==n-1)
{
t=n;
}
//记录a[i]开始时间,与下一个结束时间比较,下一个结束时间<=则cnt++;
}
printf("%d\n",cnt);
}
return 0;
}
(2)版本2(看起来比版本1简单好多是吧,但只是看起来🤔)
#include<stdio.h>
struct time{
int s1;
int e1;
}a[60000],t;
int main()
{
int n,i,j,k=0;
while(scanf("%d",&n)!=EOF)
{
if(n==0)
break; //输入0,则不处理
for(i=0;i<n;i++)
scanf("%d%d",&a[i].s1,&a[i].e1);
for(i=0;i<n;i++)
for(j=i+1;j<n;j++)
if(a[i].e1>a[j].e1)
{
t=a[i];
a[i]=a[j];
a[j]=t;//通过结束时间e1从小到大排序每个节目
}
i=0;k=1;
for(j=1;j<n;j++)
if(a[j].s1>=a[i].e1)//记录a[i]开始时间,与下一个结束时间比较,
{
k++;//下一个结束时间<=则k++
i=j;//使i等于上一个比较好的j,与下一个进行比较
}
printf("%d\n",k);
}
return 0;
}
三、时间复杂度简单计算
1、红字代码分别需要1个unit_time的执行时间,第蓝色代码都运行了n遍,所以需要2n*unit_time的执行时间,所以这段代码总的执行时间就是(2n+2)*unit_time。
2、蓝色代码都是常量级的执行时间,与n的大小无关,所以对于复杂度并没有影响。循环执行次数最多的是红色代码,所以这块代码要重点分析。前面我们也讲过,这两行代码都被执行了n次,所以总的时间复杂度就是O(n)(原本的是O(2n+2),这里省下了2n前面的2系数和2n+2后面的常量2)
int fun(int n)
{
int sum = 0;for ( int i = 1;; i <= n; ++i) {
sum = sum + i;}return sum;
}
3、如果想更好理解可以看这个:
(5条消息) 一套图 搞懂“时间复杂度”_12 26 25 的博客-CSDN博客_时间复杂度
四、空间复杂度的简单计算
1、常量空间:空间复杂度是O(1)
2、线性空间:空间复杂度记为O(n)
3、二维空间:空间复杂度记为O(nn)/O(nm)
4、递归空间:羊羊还不会🥱🥱🥱
总结
今天最大的收获应该是跳棋大师吧,没想到找到规律后那么简单,所以以后要多动手偶。还有,希望明天可以理解学长讲的算法。好了,emo🐏🐏🐑🐑要下线了。