奋斗群群赛—12
T1:Jzzhu and Children
题目位置:
题意:
主要就是有了n个孩子 ,你每次给他们 m 个糖果 ,一轮一轮的给,问你最后一个孩子的得完糖果的坐标位置!
AC代码:
#include <bits/stdc++.h>
using namespace std;
stack <int> my_stack;
int a[1005];
int main()
{
int n,m,loc;
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++)
{
scanf("%d",&a[i]);
}
for(int i=1; i<=n; i++)
a[i]=(a[i]+m-1)/m;
int max=-1;
for (int i=1; i<=n; i++)
if(a[i]>max) max=a[i];
for (int i=1; i<=n; i++)
if(a[i]==max)
{
loc=i;
}
printf("%d\n",loc);
return 0;
}
小反思:
注意向上取整!!
T2: Jzzhu and Sequences
题目位置:
题意:
输入f[1] 与f[2] 的值 而f[n]=f[n-1]+f[n+1]
求 f[n]的值的所在!
发现找规律之后会发现:
if(n%6==1)
printf("%d\n",(x+2*1000000007)%1000000007);
if(n%6==2)
printf("%d\n",(y+2*1000000007)%1000000007);
if(n%6==3)
printf("%d\n",(y-x+2*1000000007)%1000000007);
if(n%6==4)
printf("%d\n",(-x+2*1000000007)%1000000007);
if(n%6==5)
printf("%d\n",(-y+2*1000000007)%1000000007);
if(n%6==0)
printf("%d\n",(x-y+2*1000000007)%1000000007);
AC代码:
#include <bits/stdc++.h>
using namespace std;
int main()
{
long long x,y,n;
scanf("%lld%lld%lld",&x,&y,&n);
if(n%6==1)
printf("%d\n",(x+2*1000000007)%1000000007);
if(n%6==2)
printf("%d\n",(y+2*1000000007)%1000000007);
if(n%6==3)
printf("%d\n",(y-x+2*1000000007)%1000000007);
if(n%6==4)
printf("%d\n",(-x+2*1000000007)%1000000007);
if(n%6==5)
printf("%d\n",(-y+2*1000000007)%1000000007);
if(n%6==0)
printf("%d\n",(x-y+2*1000000007)%1000000007);
}
小反思:
注意取余时就是记住要 加上 2*mod!!!
T3:Jzzhu and Chocolate
题目位置:
题意:
就是一个 n*m的蛋糕 问你在切了 k 刀之后 的面积最小的那一块的最大值!
AC代码:
#include <bits/stdc++.h>
using namespace std;
int main()
{
long long n,m,k;
scanf("%lld%lld%lld",&n,&m,&k);
long long s1=0,s2=0,a,b,s;
if(n+m-2<k)
{
cout<<-1;
return 0;
}
if(n-1>=k)
{
s1=n/(k+1)*m;
}
if(m-1>=k)
{
s2=m/(k+1)*n;
}
s=max(s1,s2);
if(m-1<k&&n-1<k)
{
s=max(m/(k-n+2),n/(k-m+2));
}
cout<<s<<endl;
return 0;
}
小反思:
注意推公式的过长就好 就是 注意要”平均”的分蛋糕!
T4: Jzzhu and Cities
题目位置
题意:
一个城市,有m条道路,还有k条铁路(铁路都与点1相连),问在不改变点1到各个点的最短路的前提下最多可以删除多少条铁路
AC代码
...
T5:Jzzhu and Apples
题目位置:
题意:
有N个苹果,编号为1~N。现要将苹果组成若干对,每对苹果最小公约数不为1。求最多能分成多少对,输出各对的组成。
思路:
就是筛质数的方法就好了!
我们发现2的倍数们非常厉害,任意2个就能组成1对,所以我们先弄其他的数,最后再搞2的倍数。
我们发现一个质数x的1倍、2倍、3倍、……?这个集合的元素个数是奇数,就会多一个。为了不造成多余的影响,我们把2*x作为多出来的一个,扔到2的倍数中去。这样,各种集合的多出来的一个,肯定能找到配对。把我们使用的数标记一下,防止搞其他质数的时候重复用一个数。
先搞完3到小于等于(N/2)的质数(大于N/2,它的倍数的集合就只有它自己了,没法玩),然后搞2的倍数,把之前扔进来的2*x们和其他2*y(y是合数)组成一个大集合,两两配对,最后再多出来一个也没办法了,这已经是最多的配对了。
AC代码:
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cstring>
using namespace std;
const int N=100005;
bool prim[N];
struct apple
{
int left,right;
} a[N];
int now[N],used[N];
int main()
{
int n;
scanf("%d",&n);
memset(prim,1,sizeof(prim));
prim[2]=true;
for(int i=2; i<=100005; i++)
{
if(!prim[i]) continue;
for(int j=i+i; j<=n; j+=i)
prim[j]=false;
}
int ans=0;
for(int i=n/2; i>1; i--)
{
if(!prim[i])continue;
int tot=0;
for(int j=i; j<=n; j+=i)
{
if(used[j]==0)
now[++tot]=j;
}
if(tot&1) swap(now[2],now[tot]);
for(int j=1; j<tot; j+=2)
{
a[++ans].left=now[j];
a[ans].right=now[j+1];
used[now[j]]=used[now[j+1]]=1;
}
}
printf("%d\n",ans);
for(int i=1; i<=ans; i++)
{
printf("%d %d\n",a[i].left,a[i].right);
}
return 0;
}
总结:
1.学会向上取整 ,不要每次都错在的了最小的细节上!
2.学会推数学公式,但是不要取模太小了!
3.稳住,比赛的时候最好不要着急,因为你如果急了,你真的就完蛋了!
4.数论知识!