牛客寒假算法基础集训营3-题解

A.处女座与线性代数

链接:https://ac.nowcoder.com/acm/contest/329/A
来源:牛客网
 

题目描述

牛客寒假算法基础集训营3-题解_第1张图片

众所周知,处女座是数学大师。他定义了k维空间里的处女座点。

对于给出的k维度空间上N个点,处女座点满足:

对于这个点P和空间里任意其他两个点P1P1、P2P2,有dot(→PP1,→PP2)<0dot(PP1→,PP2→)<0。

现在给你一个k维空间和这N个点,请求出这里面所有的处女座点。

Hint: dot(→A,→B)dot(A→,B→)表示两个向量的点乘(内积)。两个向量→A={a1,a2,⋯,an}和→B={b1,b2,⋯,bn}A→={a1,a2,⋯,an}和B→={b1,b2,⋯,bn}的点乘(内积)定义为:dot(→A,→B)=a1∗b1+a2∗b2+⋯+an∗bndot(A→,B→)=a1∗b1+a2∗b2+⋯+an∗bn。

输入描述:

输入数据第一行包含一个整数T,表示用例组数。

对于每组用例,第一行两个整数 N,k。

接下来 N 行,每行k个整数,表示每个点的坐标。

输出描述:

对于每一组数据,先输出一个整数ans,表示处女座点的个数。

接下来ans行,每行k个数,表示每个处女座点的坐标。

如果有多个点满足条件,则按照输入数据中出现的顺序进行输出。

示例1

输入

复制

1
3 2
0 0
1 1
-1 -1

输出

复制

1
0 0

备注:

3≤N≤1043≤N≤104

1≤k≤101≤k≤10

T≤100T≤100

对于每一个点,保证每一维坐标的绝对值在109109以内

思路:这个题目当时做的时候就觉得无从下手,觉得数据整合的量太大,感觉应该是有一定的直接限制范围,下来之后看了官方的题解才知道的原来这种处女座点只有1个,而且最多扩展到10维空间,下面是官方的题解

作者:儒生雄才1
链接:https://ac.nowcoder.com/discuss/152781
来源:牛客网
 

1.处女座点的数量最多为 1

证明:
图片说明

2. 若K维空间一个点集{P1,P2,⋯,PnP1,P2,⋯,Pn}存在处女座点,则?≤?+?≤??+?

严格的证明需要利用高等代数。但是利用数学归纳法或线性代数方法证明同条件下证明?≤2?+1是显然的。 (提示:将处女座点的定义弱化为向量夹角为钝角或直角后即可证明)

综上所述,若?>?+2则直接输出0,否则暴力检查即可。由于?≤10,用?>2?+1判断也是可以的。
时间复杂度?(?^3)。

 

#include
using namespace std;
#define ll long long
const int maxn=1e4+10;

int a[maxn][15];
int main()
{
    int n,k,t;
    cin>>t;
    while(t--)
    {
        cin>>n>>k;
        for(int i=0; i>a[i][j];
            }
        }
        ll cnt=0;
        vector res;
        if(n>=k+3)
        {
            cout<<0<

C.处女座点名

链接:https://ac.nowcoder.com/acm/contest/329/C
来源:牛客网
 

题目描述



处女座觉得自己手上的经费可能不太够,于是决定给牛逼学生们带家教。

一天他去上课用自己的火眼金睛感觉教室里有一个学生没有来,于是他就叫学生们报出自己的学号。

已知这个班上的学号是从1开始连续编号的,处女座告诉你这个班上有多少人,想问问你到底是谁没有来。

输入描述:

输入数据共两行,第一行为一个整数N,表示班上的学生数量。

第二行为一行N-1个整数,表示已经来的学生的学号,按升序给出。

输出描述:

输出一个整数,为没有来的学生的学号。

示例1

输入

复制

3
1 3

输出

复制

2

备注:

2≤N≤200,000

这个题目就很简单,是个签到题目吧,而且读一下题目发现这个顺序还是升序给你的,真温暖啊

#include
#include
using namespace std;
int main()
{
    int n;scanf("%d",&n);
    int ans=-1;
    for(int i=1;i<=n-1;i++)
    {
        int x;
        scanf("%d",&x);
        if(x!=i&&ans==-1)
            ans=i;
    }
    if(ans==-1)
        ans=n;
    printf("%d\n",ans);
}

D.处女座的训练

链接:https://ac.nowcoder.com/acm/contest/329/D
来源:牛客网
 

题目描述

牛客寒假算法基础集训营3-题解_第2张图片

处女座靠着自己的家教本领赚够了去比赛的钱,于是开启了疯狂训练。在每个夜深人静第二天不收作业的夜晚,他都会开始刷题。

"今日又是一个刷题的夜晚。"他挑选了n道题开始刷,而题太多,刷不掉,理还乱(呜呜)、自己没有解决的题目每分钟都会给他带来bibi的疲倦值,而解决每一道题目都需要花费aiai分钟的时间。

当然,处女座一般都是考虑清楚了再写题的,所以他在写题的时候都会精神抖擞,也就是说,当前正在写的那一题并不会给他带来任何疲劳。

为了迎接后天要收的作业和明天要遇到的小姐姐,他想让今晚的刷题尽可能的轻松,那请你帮他找出最小所需要的疲倦值吧。

输入描述:

输入数据共包括n+1行,第一行包括一个n表示处女座今晚打算训练的题的数量。

接下来n行,每行包括两个整数ai,biai,bi,分别表示处女座刷掉本题要花费的时间和本题每分钟会带来的疲倦值。

输出描述:

一行包括一个整数,表示处女座今晚训练会产生的最小疲倦值。

示例1

输入

复制

6
6 1
4 5
4 3
6 2
8 1
2 6

输出

复制

86

说明

先做第6个题,增加(1+5+3+2+1)*2= 24 点疲倦值,再做第2个题,增加28点疲倦值,随后依次是第3,4,1,5道题,增加16,12,6点疲倦值。总共的疲倦值是24 + 28 + 16 + 12 + 6 = 86点。

备注:

2≤N≤1052≤N≤105.
2≤ai≤4⋅1062≤ai≤4⋅106.
1≤bi≤1000

思路:这个题目的话,我们之前是在平时训练赛的时候做过的一个题目。类似的,比这个难一点,我们做的那个带有DP,这个就是我全都要,没什么办法,

小孩子才做选择,而处女座全都要~~

类似题目的链接:https://blog.csdn.net/wentong_Xu/article/details/86498854,很类似的

#include
#include
#include
#include
#define ll long long
using namespace std;

int n;
struct node
{
    ll t,pi;
}a[100005];

bool cmp(node a,node b)
{
    return a.t*b.pi>b.t*a.pi;
}
int main()
{
    scanf("%d",&n);
    ll sum=0;
    for(int i=1;i<=n;i++)
    {
        scanf("%lld%lld",&a[i].t,&a[i].pi);
        sum+=a[i].pi;
    }
    sort(a+1,a+1+n,cmp);
    ll ans=0;
    for(int i=n;i>=1;i--)
    {
        sum-=a[i].pi;
        ans+=sum*a[i].t;
    }
    printf("%lld\n",ans);
}

E.处女座和小姐姐

链接:https://ac.nowcoder.com/acm/contest/329/E
来源:牛客网
 

题目描述

牛客寒假算法基础集训营3-题解_第3张图片

既然昨天晚上处女座已经训练了,明天才要交作业,那今天就是平淡无奇要上课的一天了。

然而处女座也想自己的小姐姐了,可是这节课是老师安排座位,处女座坐在(1,1),而小姐姐坐在(n,m)。他们之间只能通过传纸条的方式来交流感情。对于处女座而言,他上课不想过度分心,因此并不想传纸条,只在那里趁机折千纸鹤。

老师上课喜欢用"开火车"的方式让大家轮流回答问题,显然处女座作为(1,1)位,会被第一个叫起来回答,之后老师将依次叫起(2,1),(3,1),….(n,1),(n,2),(n−1,2)⋯(1,2),⋯(2,1),(3,1),….(n,1),(n,2),(n−1,2)⋯(1,2),⋯的人起来回答问题,每个人回答问题需要1秒。处女座在自己回答完以后会以每秒1个千纸鹤的速度折叠,在小姐姐开始回答问题的时候停止折叠。

处女座想知道,他这节课一共要折多少个千纸鹤?

输入描述:

输入文件包含T+1行,第一行包含一个整数T,表示用例组数。

接下来T行,每行包含两个整数n,m表示小姐姐的位置和教室的大小。

输出描述:

对于每一组用例,用一行输出一个整数,表示处女座要折的千纸鹤的个数。

示例1

输入

复制

1
3 3

输出

复制

7

备注:

2≤n,m≤1,000

思路:这个题目的话,其实没什么意思,虽然错了一发,就是列是奇数的时候和偶数的时候是不同的,详情见代码

#include
#include
using namespace std;
int main()
{
    int x,y,t;scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&x,&y);
        int ans;
        if(y%2==1.)
            ans=x*y-2;
        else
            ans=x*(y-1)-1;
        printf("%d\n",ans);
    }
}

链接:https://ac.nowcoder.com/acm/contest/329/G
来源:牛客网
 

G.处女座和小姐姐

题目描述

牛客寒假算法基础集训营3-题解_第4张图片

经过了选号和漫长的等待,处女座终于拿到了给小姐姐定制的手环,小姐姐看到以后直呼666!

处女座其实也挺喜欢6这个数字的,实际上他做手环的时候选取的k=6。所以他对于包含数码6的数字极其敏感。每次看到像4567这样的数字的时候他的心就像触电了一样,想起了小姐姐。

现在你要给处女座展示一系列数字,你想知道他的内心会激动多少次。对于同一个数字,他最多只会激动一次,即如果这个数是66666,他还是只会激动一次。

输入描述:

一行包括两个数字l,r,表示你给处女座展示的数字范围为[l,r]。

输出描述:

一行一个整数,表示处女座内心激动的次数。

示例1

输入

复制

10 20

输出

复制

1

备注:

0≤l≤r≤1018

思路:很裸的一道数位DP的题目,与不要62很类似,基本上稍稍改动就可以了,

其中sta的意义是这个数是否中间有6,如果有,那么直接为1最后统计上,

不要62的题目链接:https://blog.csdn.net/wentong_Xu/article/details/82502877

#include
#include
#include
#define ll long long
using namespace std;

ll a[22];
ll dp[22][2];
ll dfs(ll pos,ll pre,ll sta,bool limit)
{
    if(pos==-1)
        return sta; //数位到-1就代表这个数枚举完了
    if(!limit&&dp[pos][sta]!=-1)
        return dp[pos][sta];  //上一个数位没有枚举到最后这一个数枚举过了就不需要枚举了
    ll up=limit ? a[pos] : 9;//枚举数位取值
    ll tmp=0;
    for(ll i=0; i<=up; i++)
    {
        tmp+=dfs(pos-1,i,sta||i==6,limit&&i==a[pos]);
    }
    if(!limit)
        dp[pos][sta]=tmp;
    return tmp;
}

ll solve(ll x)
{
    ll pos=0;
    while(x)
    {
        a[pos++]=x%10;
        x/=10;
    }
    return dfs(pos-1,-1,0,true);
}
int  main()
{
    ll le,ri;
    cin>>le>>ri;
    memset(dp,-1,sizeof dp);
    cout<

 

I.处女座的约会

链接:https://ac.nowcoder.com/acm/contest/329/I
来源:牛客网
 

题目描述

牛客寒假算法基础集训营3-题解_第5张图片

处女座放完了"高利贷",拿到了不少的资金,又可以和小姐姐约会啦!(之前不还是攒钱打比赛的吗)现在处女座拿到了一份宁波市旅游地图决定和小姐姐一起去玩耍。他们来到了动物园,去参观里面的动物。但是很不幸的是,他们在游玩的途中遇到了一只恶龙。

 

恶龙长有n个头,但经过了处女座的调教,恶龙变得善良了一些。它的n个头每个头要么仍是邪恶的头,用“1”表示,要么已经变得善良,用“0”表示,因而恶龙的n个头就可以用n位01串来表示。而此时处女座要发挥自己的勇士形象,要把所有的龙头都变成0000⋯000000⋯00完全善良的龙头。每一次,他可以砍掉龙最右侧的一个头,同时龙会在最左侧长出新的一个头,以保证龙头数量不变。如果他砍掉的是一个1,即邪恶的头,他可以决定龙在最左侧会长出什么样的头;但如果他砍掉了一个善良的头,那么玻璃心的恶龙将会在左侧不受控制的长出一个随机的头,既可能是善良的头,也可能是邪恶的头,而且它总会与处女座作对,尽力的破坏他的计划。


现在给你一个恶龙头的初始状态,即一个01串,请帮助处女座判断一下,能否在有限步之内让全部的龙头都变成善良的龙头。

输入描述:

输入第一行T,表示用例组数。

之后T行,每行一个01串S表示龙头的初始状态,“0”表示善良的头,“1”表示邪恶的头。

输出描述:

对于每组数据,处女座能否将全部的龙头变成善良的头,可以的话输出“cnznb”,不可以则输出“ljcnz”(不含引号)。

示例1

输入

复制

1
1111

输出

复制

cnznb

备注:

T≤1000T≤1000
|S|≤100|S|≤100
注意,这个问题可能没有你想的那么简单。显然,处女座必须把一些1变成0,这样才能让1的数量减少并消失。但是如果只是简单的每次把1变成0,最终不见得能取胜。比如,如果龙头的状态是101,那么去掉最右边的1并选择在左边长出一个0,则龙头会变成010;再把010右边的0去掉后,如果左边仍长出一个1,则龙头又变回了101的状态,如此反复,将永远不能得到000。

思路:这个题目,但是想了很久,想他有没有什么坑在里面,推出了2~4的0什么样的排序都是可以完成的,然后勇敢的交了一发“处女座牛批”然后华丽的过了这个题目,那个时候没什么人过,应该也在考虑坑的问题吧,

 

你可能感兴趣的:(寒假补题)