第一题,仓库规划,初步扫了一眼发现是排序问题,但是他要求的输出并不是一个仓库的直接上级,而是所有上级中序号最小的这一个。本来以为在这种情况下只能用单调栈去做,后来发现只需要在移动index的过程中实时更新min就行了,这样复杂度就只有nlogn+n了。
然后!然后就是光荣的出错了,因为按照这种排序的思想(2,5)会排在(3,1)之后,也就是说我的代码会允许(3,1)成为(2,5)的上级,这显然是不合理的,但是一时半会我并没有发现更好的优化算法,因此只能推倒重来。
后来经过舍友大爹的指点,这题由于数据量很小,n<=1000并且m<=10,因此用暴力搜索完全可以,时间复杂度是n**2*m,最后证明确实可以暴力搜索啊啊啊啊
代码如下:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll n,m;
ll a[100][10];
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
cin>>a[i][j];
}
for(int i=1;i<=n;i++)
{
int flag=0;
for(int j=1;j<=n;j++)
{
if(j==i)
continue;
int flag2=1;
for(int k=1;k<=m;k++)
if(a[i][k]>=a[j][k])
{
flag2=0;
}
if(flag2)
{
cout<<j<<endl;
flag=1;
break;
}
}
if(!flag)
cout<<'0'<<endl;
}
return 0;
}
然后就是第二题,因子化简,这题考点也只有两个,一个埃氏筛,一个快速幂,快速幂写过几次了,这里就不在复习。主要是埃氏筛法不熟悉,这里就简单学习一下。
首先对于这题而言,由于是把一个数质因数分解,所以最多只有可能一个大于sqrt(n)的质因数,也就是说其实我们只需要用≤sqrt(n)的因数去除以这个数n,最后总能把它的质因数分解式写出来,而且由于k>1,所以实际上>根号n的因数肯定不会成为我们结果的组成部分。
下面介绍一下埃氏筛,从这提来看只需要筛选出从2到根号n的质数就行,我选择的上限是N=100010;下面上代码分析:
这短短的6行代码就能把小于根号n的质数筛选出来了。
有三个要点吧,第一,初始化所有数为质数,也就是true。
第二,为什么最上面的循环条件是i*i<=N,而不是i<=N呢?实际上我们可以看到,筛质数的时候是把小质数的倍数都筛去,也就是说,如果我目前筛选质数筛到了k,那么我k*k之下的所有不是质数的数就已经都筛选完了(因为不大于k*k所有的合数,他们的因子中一定含有小于等于k的,而我的质数已经筛选到k了,所以这些合数都被筛去了)。从这里我们就可以看到,如果我大循环的i到了k,那么实际上我就已经筛去了到k*k(含)的所有合数。所以如果我需要筛选到N的所有的质数,大循环的循环条件只需要设置i*i<=N.
那此时又有人会说,不对啊,就像你要筛选到10005的所有质数,你i最大取100,i*i取10000,怎么能到10005呢?说得好,也就是要讨论10001到10005这中间的合数如何被筛去,实际上也很明显,偶数是被2筛去的,那10001和10003以及10005分别73,7,3筛去了,这是显然的,因为这些数如果是合数的话他们一定会存在一个小于等于100的因数!一定会被筛掉!。所以这里我们可以看到,如果我取了i的最大值为100,那么我实际能筛选的范围已经达到了(100+1)(100+1)-1=10200的程度了!
再说第三点,为什么后面筛选时j是从i*i开始筛选,而不是从i开始筛选,因为小于i*i的合数一定存在小于i的因数,已经被筛去了!后面为什么步长是i?因为我这里筛掉的是i的倍数啊!j<=N应该好理解,倍数上限肯定就是N嘛。
今日日记~~~
今天大物课 听爽了😆我以为老师讲到很后面去了,结果还只是在磁介质,磁介质我预习了😊所以还是跟得上的,而且笔记也做到位了。
然后就是上完大物课带熠山去启明的咖啡厅自习,太喜欢这里了🥹🥹,点了一杯咖啡,八块八还有印花😆😆
中午吃的吉野家😄然后给今天教师节嘛给老师发祝福,老师表示很感动🥹太好了。下午有点困,效率不是很高。
晚上踏马的本来是想把CDCL看懂,顺便把vector换成链表的。但是转念一想,好像很不值得,这起码要改两节课,所以我索性就用垃圾办法,糊弄过去然后刷刷题得了。但是今晚还是改了很晚,而且人比较累,过得有点焦虑。
今天还行吧,明天继续加油😋