2010-zzuli暑假集训选拔赛(三)--解题报告

素因子

此题为数学题。

先打个素数表。n!= 1 * 2 * 3 * 4 * …… * n;注意观察,每个2的倍数的乘项都可以提一个2,可以提 n / 2个,提出来以后,就又变成1 * 2 * 3* …… * n / 2,只不过项数变少了,共有n / 2项,再将2的倍数提出来,以此类推,素因子2的个数num = n / 2 + n / 2 / 2 + ……,以此类推,将不大于n的素数的个数都用这种方法计算出来。

 
  
#include < stdio.h >
#include
< string .h >
#define NN 10002

int index;
int prime[NN];

void Prepare()
{

int i, j;
int mark[NN];
memset(mark,
0 , sizeof (mark));
index
= 0 ;
for (i = 2 ; i < NN; i ++ ){
if ( ! mark[i]){
prime[index
++ ] = i;
for (j = i * i; j < NN; j += i)
mark[j]
= 1 ;
}
}
}

int Cnt( int t, int n)
{
int cnt = 0 ;
while (t <= n){
n
/= t;
cnt
+= n;
}

return cnt;
}

int main()
{
int n, i, j;
int ans[NN];
Prepare();
while (scanf( " %d " , & n) != EOF){
for (i = 0 ; i < index; i ++ ){
if (prime[i] > n)
break ;
ans[i]
= Cnt(prime[i], n);
}

for (j = 0 ; j < i; j ++ ){
printf(
" %d %d\n " , prime[j], ans[j]);
}
}
return 0 ;
}

 

 

洗衣服

此题为数学题。

代码最短的一个,衣服里剩余的洗衣粉函数y = a*[(b /(t / k + b))^k],a表示刚开始衣服里所含的水,此函数是k的减函数,所以直接取k = n即可。

 

 
  
#include < stdio.h >

int main()
{
int n;
while (scanf( " %*d%*d%d " , & n) != EOF){
printf(
" %d\n " , n);
}
return 0 ;
}

 

 

第k个序列

此题为数学题。

如果是序列2 1 3 4 5,如何判断它是第几个序列呢,既然是递增的,必然首位是1的都在它前面,首位是1的有4!种排列。如此给你一个长为n的序列,如何判断它是第几个序列呢,从首位开始循环,第i位是m,则前i-1为不变,因为i的变动而增加的序列数num = (m - 1) * ((n – i )!)。如此逆推过来即可。

 

 

 

破译密码

此题是hdu1287,非原创,考察位运算。

核心算法:如果 a^b=c那么 a^c=b,b^c=a;用双重for循环找到所给密文是跟哪个字符异或运算的结果,再将密文与子字符异或运算一便即可。

 

夹角

 

此题最水。

唯一注意的一点就是夹角范围是0—180度。解题步骤见代码。

 

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
#include < stdio.h >
#include
< stdlib.h >
#include
< math.h >
int main()
{
double x1, x2, ans;
int h, m;
while (scanf( " %d:%d " , & h, & m) != EOF){
if (h >= 12 )
h
-= 12 ;
x1
= 1.0 * m / 2 + h * 30 ;
x2
= 6.0 * m;
ans
= fabs(x1 - x2);
if (ans >= 180 ){
ans
= 360 - ans;
}
printf(
" %.2lf\n " , ans);
}
return 0 ;
}

 

迷宫

 

此题为深搜。

只因上次去新区讲过,就出了道,让大家练练,没有一点技巧,没有剪枝,旨在让大家熟悉dfs的模板式代码。见代码。

 

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
#include < stdio.h >
#include
< string .h >
#define NN 12
int n, ok, ans, mark[NN][NN], map[NN][NN];
int dir[ 4 ][ 2 ] = {
1 , 0 ,
0 , 1 ,
- 1 , 0 ,
0 , - 1
};

void dfs( int x, int y){
int i, cx, cy;

if (mark[x][y])
return ;
mark[x][y]
= 1 ;

ans
+= map[x][y];
if (x == n - 1 && y == n - 1 ){
if (ans == 0 ){
ok
= 1 ;
}
else {
mark[x][y]
= 0 ;
ans
-= map[x][y];
}
return ;
}
for (i = 0 ; i < 4 ; i ++ ){
cx
= x + dir[i][ 0 ];
cy
= y + dir[i][ 1 ];

if (cx >= 0 && cx < n && cy >= 0 && cy < n)
dfs(cx, cy);
if (ok) return ;
}
mark[x][y]
= 0 ;
ans
-= map[x][y];

}
int main()
{
int i, j;
while (scanf( " %d " , & n) != EOF){
for (i = 0 ; i < n; i ++ ){
for (j = 0 ; j < n; j ++ ){
scanf(
" %d " , & map[i][j]);
}
}
ok
= 0 ;
ans
= 0 ;
memset(mark,
0 , sizeof (mark));
dfs(
0 , 0 );
if (ok) puts( " YES " );
else puts( " NO " );
}
return 0 ;
}

转载于:https://www.cnblogs.com/superbin/archive/2010/07/07/1773034.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值