目录
小朋友崇拜圈
题目描述
班里 NN 个小朋友,每个人都有自己最崇拜的一个小朋友(也可以是自己)。
在一个游戏中,需要小朋友坐一个圈,每个小朋友都有自己最崇拜的小朋友在他的右手边。
求满足条件的圈最大多少人?
小朋友编号为 1,2,3,\cdots N1,2,3,⋯N。
输入描述
输入第一行,一个整数 N(3<N<10^5)N(3<N<105)。
接下来一行 NN 个整数,由空格分开。
输出描述
要求输出一个整数,表示满足条件的最大圈的人数。
输入输出样例
示例
输入
9 3 4 2 5 3 8 4 6 9
输出
4
样例解释
如下图所示,崇拜关系用箭头表示,红色表示不在圈中。
显然,最大圈是[2 4 5 3] 构成的圈。
代码:
#include <bits/stdc++.h>
using namespace std;
int a[100001];//存储小朋友们的对象
int start,sum=0;//起始位置和最大圈人数
int vis[100010]={0};//标记走没走过
void dfs(int k,int cnt)//k代表当前位置,cnt代表当前圈人数
{
if(vis[k]==1&&k==start)//结束条件①该点走过②围成了一个圈
{
if(cnt>sum)
sum=cnt;//保持sum为最大圈人数(贪心策略)
return;
}
vis[k]=1;//标记
dfs(a[k],cnt+1);//递归继续扩展圈圈
vis[k]=0;//回溯
}
int main()
{
// 请在此输入您的代码
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];//利用数组存储小朋友i们的对象
}
for(int i=1;i<=n;i++)
{
start=i;//找出每个小朋友作为起点的圈圈
dfs(i,0);//i代表起点,0代表目前为0个
}
cout<<sum;//经过一番递归得到的是最大的圈圈
return 0;
}
分巧克力
题目描述
儿童节那天有 K 位小朋友到小明家做客。小明拿出了珍藏的巧克力招待小朋友们。
小明一共有 NN 块巧克力,其中第 ii 块是 H_i \times WiHi×Wi 的方格组成的长方形。为了公平起见,
小明需要从这 NN 块巧克力中切出 K 块巧克力分给小朋友们。切出的巧克力需要满足:
形状是正方形,边长是整数;
大小相同;
例如一块 6x5 的巧克力可以切出 6 块 2x2 的巧克力或者 2 块 3x3 的巧克力。
当然小朋友们都希望得到的巧克力尽可能大,你能帮小明计算出最大的边长是多少么?
输入描述
第一行包含两个整数 N,KN,K (1 \leq N, K \leq 10^51≤N,K≤105)。
以下 N 行每行包含两个整数 H_i,W_iHi,Wi (1 \leq H_i, W_i \leq 10^51≤Hi,Wi≤105)。
输入保证每位小朋友至少能获得一块 1x1 的巧克力。
输出描述
输出切出的正方形巧克力最大可能的边长。
输入输出样例
示例
输入
2 10 6 5 5 6
输出
2
代码:
#include<bits/stdc++.h>
using namespace std;
int n,m,a[100001],b[100001];
int ans=0;//记录结果
int check(int k)
{
int cnt=0;
for(int i=1;i<=n;i++)
{
cnt+=((a[i]/k)*(b[i]/k));
//可以切割成的边长为k的正方形巧克力的块数为:(H/k)*(W/k)
}
if(cnt>=m)
{
ans=k;
return 1;
}
return 0;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>a[i]>>b[i];
int i=0,j=100001;//所给范围
while(i<=j)
{
int mid=(i+j)/2;//二分法将mid看作边长
if(check(mid))//假如已经符合就继续往上查找
i=mid+1;//找到符合题意的最大边长
else
j=mid-1;//往下查找
}
cout<<ans;
}