Problem A: pigofzhou的巧克力棒
Description
Input
输入数据为T组(T <= 10000),每组数据读入一个n(n<=1000000000)
Output
一行一个整数代表能获得的最大高兴值
Sample Input
Sample Output
HINT
题目链接:http://gdutcode.sinaapp.com/problem.php?cid=1049&pid=0
ps:关于这题 数学不好就真的只能找规律了。
首先 关于查找n!中k的因子是有数学公式的:
n!=n*(n-1)(n-2)……3*2*1
=(k*2k*3k…..*mk)*a a是不含因子k的数的乘积,显然m=n/k;
=(k^m)*(1*2*3…*m)*a
=k^m*m!*a
比如说例子代码:
int gs(int n,int k)
{
int num=0;
while(n)
{
num+=n/k;
n/=k;
}
return num;
}
下面给出AC代码:
#include <bits/stdc++.h>
using namespace std;
int main()
{
int T;
long long n,sum;
while(scanf("%d",&T)!=EOF)
{
while(T--)
{
sum=;
scanf("%lld",&n);
while(n)
{
sum+=(n/);
n/=;
}
printf("%lld\n",sum);
}
}
return ;
}
Problem B: Zhazhahe究竟有多二
Description
Zhazhahe竟然能二到把耳机扔到洗衣机里去洗,真的是二到了一种程度,现在我们需要判断一下zhazhahe二的程度(就是计算zhazhahe的脑残值有几个2的因子),下面给你一个n,n!表示zhazhahe的脑残值。
Input
输入一个正整数t(0<t<3000)表示样例组数,每组样例输入一个正整数n(0<n<1e18),n!表示zhazhahe的脑残值
Output
输出一个正整数表示zhazhahe二的程度
Sample Input
Sample Output
HINT
题目链接:http://gdutcode.sinaapp.com/problem.php?cid=1049&pid=1
题解:思路和上一题基本上是一样的,代码几乎相同!不理解看上一题的题解!
下面给出AC代码:
#include <bits/stdc++.h>
using namespace std;
int main()
{
int T;
long long n,ans,i,sum;
while(scanf("%d",&T)!=EOF)
{
while(T--)
{
scanf("%lld",&n);
sum=;
while(n)
{
n/=;
sum+=n;
}
printf("%lld\n",sum);
}
}
return ;
}
Problem C: 剁手女生节
Description
由于女生节准备到了,ming打算给班上女生送一份大礼。没错,就是数学练习册!
ming先前就已经收藏了 n 本练习册了,一直不舍得做,这次突然决定把它们都拿出来当作礼物送出去!
但是,ming班上一共有 4 个女生,为了不要显得自己偏爱哪一个,他觉得每个女生都应该分到同等数量的练习册。
这样的话,原来的 n 本就可能不太够了。于是他去逛亚马当商城。
他发现,最近ACM(Association of Counting Method)又出版了好多新版数学练习册:高数、线代、离散、概率论…
而且商店有三种促销优惠套餐:
第一种:任选 1 本练习册,送欧几里德主题套尺。只需 a 个比特币;
第二种:任选 2 本练习册,送莱布尼兹同款2B铅笔。只需 b 个比特币;
第三种:任选 3 本练习册,送爱因思坦专用橡皮擦。只需 c 个比特币。
那么问题来了:吃土ming如何用最少的比特币购买若干本练习册,使得全部(包括原来的n本)可以平分给四个女生?
Input
每组输入是一行四个整数:n,a,b,c(1 <= n,a,b,c <= 1e9)意思如题目描述。
Output
对每组输入,输出一行一个整数,表示ming要花的最少的比特币数。
Sample Input
Sample Output
HINT
题目链接:http://gdutcode.sinaapp.com/problem.php?cid=1049&pid=2
思路:三种情况,讨论即可!给出两种写法:
#include <bits/stdc++.h>
#define ll long long int
using namespace std;
int main()
{
ll t;
scanf("%lld",&t);
while(t--)
{
ll n,a,b,c;
scanf("%lld%lld%lld%lld",&n,&a,&b,&c);
if(n%==)
printf("0\n");
else
{
ll x=(-(n%));
if(x==)printf("%lld\n",min(min(a,c*),c+b));
if(x==)printf("%lld\n",min(min(*a,b),c*));
if(x==)printf("%lld\n",min(min(*a,a+b),c));
}
}
return ;
}
DP写法:
#include <bits/stdc++.h>
using namespace std;
long long dp[];
const long long inf=<<;
void init(int x)
{
for(int i=;i<=;i++)
dp[i]=i?inf:;
}
int main()
{
int m[];
int T,n,x;
while(scanf("%d",&T)!=EOF)
{
while(T--)
{
scanf("%d",&n);
for(int i=;i<=;i++)
scanf("%d",&m[i]);
x=n%;
if(!x)
cout<<<<endl;
else
{
init(x);
for(int i=;i<=-x;i++)
for(int j=;j<=;j++)
if(i>=j)
dp[i]=min(dp[i],dp[i-j]+m[j]);
long long minx=inf;
for(int j=;j<=;j++)
minx=min(minx,dp[j*-x]);
printf("%lld\n",minx);
}
}
}
return ;
}
Problem D: 勤奋的涟漪2
Description
涟漪进入集训队后,他会去实验室训练或者去操场锻炼。 接下来n天,每天的情况是一下4种中的一种: 1.当天体育馆关门了和没有训练赛 2.当天体育馆关门了和有训练赛 3.当天体育馆开放和没有训练赛 4.当天体育馆开放和有训练赛 涟漪知道之后n天的情况。 涟漪每一天可以休息,或者打训练赛(当天有训练赛)或者运动(当天体育馆开放)。 涟漪要制定一个训练计划,决定每天干什么,但是涟漪不会连续两天都运动或者连续两天都打训练赛, 请帮涟漪找出她最少休息的天数(她不打训练赛和运动)。 休息的时候,她会做下面的数学题
Input
Output
输出 一个数 表示(涟漪休息的天数) 乘以(数学题的答案的积)。
Sample Input
Sample Output
HINT
题目链接:http://gdutcode.sinaapp.com/problem.php?cid=1049&pid=3
分析:四次导数,结果为-24,注意这个好像没有什么了!
下面给出AC代码:
#include <bits/stdc++.h>
using namespace std;
const int MAX=;
int n,a[MAX];
int main()
{
int T;
cin>>T;
while(T--)
{
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%d",&a[i]);
int l=;
while(a[l]==) l++;
for(int i=l+;i<=n;i++)
{
if(a[i]==)
{
if(a[i-]!=) a[i]=-a[i-];
}
else
{
if(a[i]==a[i-]) a[i]=;
}
}
int ans=;
for(int i=;i<=n;i++)
{
if(!a[i]) ans++;
}
cout<<ans*(-)<<endl;
}
return ;
}
Problem E: 穷游中国在统题
Description
Input
Output
Sample Input
Sample Output
HINT
题目链接:http://gdutcode.sinaapp.com/problem.php?cid=1049&pid=4
思路:
#include<bits/stdc++.h>
using namespace std;
const int N=+;
struct zxc
{
int xx,mm;
} a[N];
bool cmp(struct zxc x,struct zxc y)
{
return x.mm<y.mm;
}
int main()
{
int t,c=;
cin>>t;
while(t--)
{
int n,i,j;
cin>>n;
for(i=; i<=n; i++)
{
a[i].xx=i;//记录原先所在的位置
cin>>a[i].mm;
}
stable_sort(a+,a+n+,cmp);//稳定排序
int tot=;
i=;
while(i<=n)
{
tot++;
int k=a[i].xx;
for(j=i; j<=k; j++)//相交的区间合并
if(a[j].xx>k)
k=a[j].xx;
i=k+;
}
cout<<tot<<endl<<endl;
}
}
Problem F: 神偷TMK
Description
Input
Output
Sample Input
Sample Output
HINT
题目链接:http://gdutcode.sinaapp.com/problem.php?cid=1049&pid=5
思路:这道题就不说了,输出ab!
下面给出AC代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
cout<<'a'<<'b'<<endl;
return ;
}
Problem G: 神偷TMK后续
Description
Input
Output
Sample Input
Sample Output
HINT
题目链接:http://gdutcode.sinaapp.com/problem.php?cid=1049&pid=6
思路:一个组合问题,求C(n,k);
下面给出AC代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,k;
while(~scanf("%d%d",&n,&k))
{
int a=,b=,c=;//一定要赋值1;
for(int i=n;i>=; i--)
a*=i;
for(int i=k; i>=; i--)
b*=i;
for(int i=(n-k); i>=; i--)
c*=i;
printf("%d\n",a/(b*c));
}
return ;
}
Problem H: 《为什么会变成这样呢》
Description
Input
Output
Sample Input
Sample Output
HINT
题目链接:http://gdutcode.sinaapp.com/problem.php?cid=1049&pid=7
思路:
Single number 问题,其他数都出现了k(k>1)次,只有一个数出现了一次,求这个数。
考虑把出现了多次数消掉,如果k是偶数,则可用异或法;如果k是奇数,则可以用求和再求余法,出现k次的数模k为0,和里最终剩下的是那个single
number %k,还是不行,再利用一个性质,小于k的数对k取模就是这个数本身,分别求single number的每一位
#include <iostream>
#include <cstdio>
using namespace std;
unsigned long long FindFirstBitIs1 (long long num){
long long indexBit = ;
while ((num & ) == && indexBit < ){
num >>= ;
++indexBit;
}
return indexBit;
} long long IsBit1 (long long data, unsigned long long indexof1){
data >>= indexof1;
return data & ;
} void FindNumsAppearOnce (long long data[], long long n, long long &num1, long long &num2){
long long result = ;
long long i;
for (i=; i<n; ++i){
result ^= data[i];
}
unsigned long long indexof1 = FindFirstBitIs1 (result);
num1 = ;
num2 = ;
for (i=; i<n; ++i){
if (IsBit1 (data[i], indexof1))
num1 ^= data[i];
else
num2 ^= data[i];
}
} int main(){
int T;
cin>>T;
while(T--){
long long num1 = ,num2 = ;
long long n;
scanf("%lld",&n);
long long *a=new long long[n];
for(long long i=;i<n;i++){
scanf("%lld",&a[i]);
}
FindNumsAppearOnce(a,n,num1,num2);
printf("%lld %lld\n",min(num1,num2),max(num1,num2));
delete[] a;
}
return ;
}
Problem I: 只会做水题的jiakin
Description
听说ACM新生杯来了许多大佬,吓得只会做水题的jiakin开始做水题。 题目在一个n行m列二维网格中,位于右下角的格子。现在有若干种水管,类型及状态如下:
在网格中有一些格子布置着水管(只有一种类型一种状态),现在jiakin从最左上的格子开始灌水(即最左上的格子一直有水),且水只能沿水管向右或者向下流,问:jiakin能否成功做好水题。(如图:满足条件)
Input
第一行一个整数T(T < 10),代表T组测试数据。 每组数据第一行有两个整数n和m(n,m<=1000),表示网格的行数和列数。 接下去n行,每行有m个格式为(x,y)的一组数据,代表水管的类型和状态,其中(0,0)表示没水管。
Output
对每组数据第一行“Case x:”,x代表第x组数据。 第二行如果jiakin能成功水题则输出“Well done!”,否则输出“What a pity!”.
Sample Input
Sample Output
HINT
题目链接:http://gdutcode.sinaapp.com/problem.php?cid=1049&pid=8
思路:只要理顺就好了!
下面给出AC代码:
#include <cstdio>
#include <iostream>
#include <climits>
#include <cstring> using namespace std; struct node{
int x,y;
}g[][]; bool f[][]; int main(){
freopen("input.txt","r",stdin);
int T,n,m;
scanf("%d\n",&T);
for(int cnt=;cnt<=T;cnt++){
scanf("%d %d\n",&n,&m);
for(int i=;i<=n;i++){
for(int j=;j<=m;j++)scanf("(%d,%d)",&g[i][j].x,&g[i][j].y);
getchar();
}
memset(f,,sizeof f);
f[][]=;
for(int i=;i<=n;i++)
for(int j=;j<=n;j++){
if(i==&&j==) continue;
if(g[i][j].x==&&g[i][j].y==){ //2 4
f[i][j]=;
continue;
}
if(g[i][j].x==&&g[i][j].y==){//2 5
f[i][j]=;
continue;
} if(g[i][j].x==&&g[i][j].y==&&
((g[i][j-].x==&&g[i][j-].y==)
||(g[i][j-].x==&&g[i][j-].y==)
||(g[i][j-].x==&&g[i][j-].y==)
||(g[i][j-].x==&&g[i][j-].y==)
||(g[i][j-].x==&&g[i][j-].y==))) f[i][j]=f[i][j-]; //(2,0) if(g[i][j].x==&&g[i][j].y==&&
((g[i-][j].x==&&g[i-][j].y==)
||(g[i-][j].x==&&g[i-][j].y==)
||(g[i-][j].x==&&g[i-][j].y==)
||(g[i-][j].x==&&g[i-][j].y==)
||(g[i-][j].x==&&g[i-][j].y==)
||(g[i-][j].x==&&g[i-][j].y==))) f[i][j]=f[i-][j]; //(2,1) if(g[i][j].x==&&g[i][j].y==&&
((g[i][j-].x==&&g[i][j-].y==)
||(g[i][j-].x==&&g[i][j-].y==)
||(g[i][j-].x==&&g[i][j-].y==)
||(g[i][j-].x==&&g[i][j-].y==)
||(g[i][j-].x==&&g[i][j-].y==))) f[i][j]=f[i][j-]; //(2,2) if(g[i][j].x==&&g[i][j].y==&&
((g[i-][j].x==&&g[i-][j].y==)
||(g[i-][j].x==&&g[i-][j].y==)
||(g[i-][j].x==&&g[i-][j].y==)
||(g[i-][j].x==&&g[i-][j].y==)
||(g[i-][j].x==&&g[i-][j].y==)
||(g[i-][j].x==&&g[i-][j].y==))) f[i][j]=f[i-][j]; //(2,3) if(g[i][j].x==&&g[i][j].y==&&
((g[i][j-].x==&&g[i][j-].y==)
||(g[i][j-].x==&&g[i][j-].y==)
||(g[i][j-].x==&&g[i][j-].y==)
||(g[i][j-].x==&&g[i][j-].y==)
||(g[i][j-].x==&&g[i][j-].y==))) f[i][j]=f[i][j-]; //(3,0) if(g[i][j].x==&&g[i][j].y==&&
((g[i-][j].x==&&g[i-][j].y==)
||(g[i-][j].x==&&g[i-][j].y==)
||(g[i-][j].x==&&g[i-][j].y==)
||(g[i-][j].x==&&g[i-][j].y==)
||(g[i-][j].x==&&g[i-][j].y==)
||(g[i-][j].x==&&g[i-][j].y==))) f[i][j]=f[i-][j]; //(3,3) if(g[i][j].x==&&g[i][j].y==){
if((g[i-][j].x==&&g[i-][j].y==)
||(g[i-][j].x==&&g[i-][j].y==)
||(g[i-][j].x==&&g[i-][j].y==)
||(g[i-][j].x==&&g[i-][j].y==)
||(g[i-][j].x==&&g[i-][j].y==)
||(g[i-][j].x==&&g[i-][j].y==)) f[i][j]=f[i-][j];
if(f[i][j]) continue;
if((g[i][j-].x==&&g[i][j-].y==)
||(g[i][j-].x==&&g[i][j-].y==)
||(g[i][j-].x==&&g[i][j-].y==)
||(g[i][j-].x==&&g[i][j-].y==)
||(g[i][j-].x==&&g[i][j-].y==)) f[i][j]=f[i][j-];
}
if(g[i][j].x==&&g[i][j].y==){
if((g[i-][j].x==&&g[i-][j].y==)
||(g[i-][j].x==&&g[i-][j].y==)
||(g[i-][j].x==&&g[i-][j].y==)
||(g[i-][j].x==&&g[i-][j].y==)
||(g[i-][j].x==&&g[i-][j].y==)
||(g[i-][j].x==&&g[i-][j].y==)) f[i][j]=f[i-][j];
if(f[i][j]) continue;
if((g[i][j-].x==&&g[i][j-].y==)
||(g[i][j-].x==&&g[i][j-].y==)
||(g[i][j-].x==&&g[i][j-].y==)
||(g[i][j-].x==&&g[i][j-].y==)
||(g[i][j-].x==&&g[i][j-].y==)) f[i][j]=f[i][j-];
}
if(g[i][j].x==&&g[i][j].y==){
if((g[i-][j].x==&&g[i-][j].y==)
||(g[i-][j].x==&&g[i-][j].y==)
||(g[i-][j].x==&&g[i-][j].y==)
||(g[i-][j].x==&&g[i-][j].y==)
||(g[i-][j].x==&&g[i-][j].y==)
||(g[i-][j].x==&&g[i-][j].y==)) f[i][j]=f[i-][j];
if(f[i][j]) continue;
if((g[i][j-].x==&&g[i][j-].y==)
||(g[i][j-].x==&&g[i][j-].y==)
||(g[i][j-].x==&&g[i][j-].y==)
||(g[i][j-].x==&&g[i][j-].y==)
||(g[i][j-].x==&&g[i][j-].y==)) f[i][j]=f[i][j-];
}
}
if(f[n][m]){
printf("Case %d:\n",cnt);
puts("Well done!");
}
else{
printf("Case %d:\n",cnt);
puts("What a pity!");
}
} return ;
}
Problem J: 质方数
Description
小z很喜欢研究各种各样的数字,最近他迷上了质数和平方数,他把一个质数的平方命名为”质方数”,现在他想知道,给出一个正整数,距离这个正整数最近的质方数是什么?(如果有2个距离相等的质方数,选择较小的一个)
Input
输入数据组数为T(T<=50),每组数据输入一个正整数n,其中1<=n<=100,000,000;
Output
对于每个测试样例,输出距离最近的质方数,每个样例占一行。
Sample Input
Sample Output
HINT
题目链接:http://gdutcode.sinaapp.com/problem.php?cid=1049&pid=9
思路:打表吧!之前也不知道懵了哪里,怎么都不会过,还有这道题很坑,官方数据都是有问题的!我只能膜拜出题君了!
下面给出AC代码:
#include <bits/stdc++.h>
using namespace std;
bool gcd(int n)
{
if(n==)
return true;
else
{
for(int i=;i<=sqrt((double)n);i++)
if(n%i==)
return false;
}
return true;
}
int main()
{
int T,n;
while(scanf("%d",&T)!=EOF)
{
while(T--)
{
scanf("%d",&n);
int count1,count2;
int c;
if(n==)
cout<<<<endl;
if(n==)
cout<<<<endl;
else if(n>=)
{
int x=n;
int y=n;
while(x--)
if(gcd(x))
{
count1=n-x;
break;
}
while(y++)
if(gcd(y))
{
count2=y-n;
break;
}
if(count1<=count2)
{
n=x;
c=count1;
}
else
{
n=y;
c=count2;
}
cout<<n*n<<endl;
}
}
}
return ;
}