2016广东工业大学新生杯决赛网络同步赛暨全国新生邀请赛
几个写出来了的题目
A.
`#include
#include<stdio.h>
int main(void)
{
long long t,i,j,k,ans,w,s;
long long n;
scanf("%lld",&t);
for (k=1;k<=t;k++)
{
scanf("%lld",&n);
ans=0;
while(n)
{
n/=2;
ans+=n;
}
printf("%lld\n",ans);
}
return 0;
}
其实和A题一样,但比赛时想了很久…
n!=1*2*3*…..*n,其中有2的因子的有2,4,6…..,数量为n/2。
取出这些数然后/2,便形成了新的序列1,2,3,4…..,即缩小了问题的规模。
所以只要重复操作即可。
C.
#include<stdio.h>
long long dp[10000];
int min(int a, int b)
{
if (a>b) return b;
else return a;
}
int main(void)
{
int n, a, b, c, t, i, j, k, yu, ans;
scanf("%d", &t);
for (k = 1;k <= t;k++)
{
scanf("%d %d %d %d", &n, &a, &b, &c);
if (n % 4 == 0)
{
printf("%d\n", 0);
continue;
}
dp[1] = a;
dp[2] = min(2 * a, b);
dp[3] = min(min(dp[2] + dp[1], dp[1] * 3), c);
yu = 4 - n % 4; ans = dp[yu];
for (i = 4;i <= 30;i++)
{
dp[i] = min(min(dp[i - 1] + a, dp[i - 2] + dp[2]), dp[i - 3] + dp[3]);
if (dp[i]<ans && i % 4 == yu) ans = dp[i];
}
printf("%d\n", ans);
}
return 0;
}
动态规划.dp[i]存放买i本书所需的最小花费。
所以状态转移方程dp[i]=min(dp[i-3]+dp[3],min(dp[i-1]+dp[1],dp[i-2]+dp[2]))
其中dp[1]=a(只有1种买法)
dp[2]=min(a*2,b)(买2个1本或1个2本)
dp[3]=min(c,min(a*3,dp[2]+a))(3个1本,1个1本+1个2本,1个3本)
需要购买的数量为(4-n%4)+4*k本(k为任意自然数)
我的想法:需要买的本数最多的情况是全买1次3本的直到够分,所以dp算到15。
实际上,只有更少的情况:
对于余数为1的情况:买1个1本 ,或者买1个2本+1个3本,或者买3个3本
(a,b,c大于0,不确定的只有这三个数之间的大小关系.其他情况都比这三种情况大)
对于余数为2的情况:买1个2本,或者买2个1本,或者买2个3本
(对于买1个1本1个3本,必定在a+a和c+c之间,所以不予考虑)
对于余数为3的情况:买1个3本,或者买3个1本,或者买1个2本1个1本。
另外:虽然n,a,b,c在1e9以内,但因为涉及到3*a,所以会超出int范围
(我就是因为这个始终没有想明白为什么wrong answer….)
F.
#include<stdio.h>
#include<string.h>
int main(void)
{
printf("ac");
return 0;
}
水题
G.
#include<stdio.h>
int main(void)
{
int n,k,i,j,z,x;
while (scanf("%d %d",&n,&k)!=EOF)
{
z=1; x=1;
for (i=n;i>=n-k+1;i--) z=z*i;
for (i=k;i>=2;i--) x=x*i;
if (x==0) z=1;
else z=z/x;
printf("%d\n",z);
}
return 0;
}
水题.求组合数
I.
#include<stdio.h>
struct zt
{
int left;
int right;
int up;
int down;
};
int ans;
int n, m;
struct zt tu[1010][1010] = { 0 };
void solve(int x, int y)
{
if (ans == 1) return;
if (x == n && y == m)
{
printf("Well done!\n");
ans = 1;
}
if (tu[x][y].right == 1 && tu[x][y + 1].left == 1)
solve(x, y + 1);
if (tu[x][y].down == 1 && tu[x + 1][y].up == 1)
solve(x + 1, y);
return;
}
int main(void)
{
int t, i, j, k, x, y;
char v, b,l;
scanf("%d", &t);
for (i = 1;i <= t;i++)
{
scanf("%d %d", &n, &m);
for (i = 1;i <= n;i++)
for (j = 1;j <= m;j++)
{
tu[i][j].left = 0;
tu[i][j].right = 0;
tu[i][j].up = 0;
tu[i][j].down = 0;
}
for (i = 1;i <= n;i++)
{
getchar();
for (j = 1;j <= m;j++)
{
scanf("%c%d%c%d%c", &v, &x, &l, &y, &b);
switch (x)
{
case 3:
switch (y)
{
case 0:
tu[i][j].left = 1;
tu[i][j].right = 1;
tu[i][j].down = 1;
break;
case 1:
tu[i][j].up = 1;
tu[i][j].left = 1;
tu[i][j].down = 1;
break;
case 2:
tu[i][j].up = 1;
tu[i][j].left = 1;
tu[i][j].right = 1;
break;
default:
tu[i][j].up = 1;
tu[i][j].right = 1;
tu[i][j].down = 1;
break;
}
break;
case 4:
tu[i][j].up = 1;
tu[i][j].down = 1;
tu[i][j].right = 1;
tu[i][j].left = 1;
break;
case 0:
break;
default:
switch (y)
{
case 0:
tu[i][j].left = 1;
tu[i][j].right = 1;
break;
case 1:
tu[i][j].up = 1;
tu[i][j].down = 1;
break;
case 2:
tu[i][j].left = 1;
tu[i][j].down = 1;
break;
case 3:
tu[i][j].up = 1;
tu[i][j].right = 1;
break;
case 4:
tu[i][j].up = 1;
tu[i][j].left = 1;
break;
case 5:
tu[i][j].down = 1;
tu[i][j].right = 1;
break;
}
break;
}
}
}
ans = 0;
solve(1, 1);
if (ans == 0)
printf("What a pity!\n");
}
return 0;
}
深度优先搜索,若向右或下走得通(该点的右边(下边)有路,且目标点的左边(上边)有路),那么就去尝试.找到一条路径后退出。
J.
#include<stdio.h>
#include<math.h>
int main(void)
{
int t,n,i,j,k,find,x,left,right;
scanf("%d",&t);
for (k=1;k<=t;k++)
{
scanf("%d",&n);
find=1; x=n;
while (find)
{
int m=sqrt(x);
if (sqrt(x)*sqrt(x)==x)
{
for (i=2;i<=sqrt(m);i++)
{
if (m%i==0) break;
}
if (i>sqrt(m)) {find=0; right=x;}
}
if (find==1) x++;
}
find=1;
x=n-1;
while (find && x>1)
{
int m=sqrt(x);
if (sqrt(x)*sqrt(x)==x)
{
for (i=2;i<=sqrt(m);i++)
{
if (m%i==0) break;
}
if (i>sqrt(m)) {find=0; left=x;}
}
if (find==1) x--;
}
if (find==1) printf("%d\n",right);
else if (right-n<n-left) printf("%d\n",right);
else printf("%d\n",left);
}
return 0;
}
分别向后搜索、向前搜索,先判断是否为平方数,再取平方根进行素数判断,最后取距离小的。
总之,作为一个新生,还是有很多需要改进的地方。程序只作参考,不一定是简单的思路。