又是一年的校赛的季节,今年的校赛的题目感觉上还是不是那么的难,我和队友一起4个小时完成了所有的题目。总之感谢他们,在做题的时候提出了很多有益的建议和测试数据。虽然最后因为罚时只是位居第二,但是,我为你们感到骄傲!!
第一题
题目描述
Now you are asked to measure a dose of medicine with a balance and a number of weights. Certainly it is not always achievable. So you should find out the qualities which cannot be measured from the range [1,S]. S is the total quality of all the weights.
解题报告
这道题实际上就是背包问题的一个翻版,在天平上,砝码既可以放在左边,也可以放在右边,就是一个两次做循环的双肩背包。只要按照要求写就可以了, 算法复杂度为O(n*sum).
source code
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAXN 105
#define MAXM 10005
int weight[MAXN];
int n;
int dp[MAXM];
int sum;
void Input()
{
sum = 0;
int i;
for(i = 1; i <= n; i++){
scanf("%d",&weight[i]);
sum += weight[i];
}
}
void Solve()
{
int i,j;
int ans = 0;
memset(dp,0,sizeof(dp));
dp[0] = 1;
for(i=1;i<=n;i++){
for(j=sum;j>=weight[i];j--){
if(dp[j-weight[i]]){
dp[j] = 1;
}
}
for(j=0;j<=sum;j++){
if(dp[j]){
dp[abs(j-weight[i])] = 1;
}
}
}
for(i=1;i<=sum;i++){
if(!dp[i])ans++;
}
printf("%d\n",ans);
if(ans){
for(i=1;i<=sum;i++){
if(!dp[i]){
printf("%d",i);
if(--ans)printf(" ");
}
}
printf("\n");
}
return;
}
int main()
{
while(scanf("%d",&n)!=EOF){
Input();
Solve();
}
return 0;
}
第二题
题目描述
Jimmy experiences a lot of stress at work these days, especially since his accident made working difficult. To relax after a hard day, he likes to walk home. To make things even nicer, his office is on one side of a forest, and his house is on the other. A nice walk through the forest, seeing the birds and chipmunks is quite enjoyable.
The forest is beautiful, and Jimmy wants to take a different route everyday. He also wants to get home before dark, so he always takes a path to make progress towards his house. He considers taking a path from A to B to be progress if there exists a route from B to his home that is shorter than any possible route from A. Calculate how many different routes through the forest Jimmy might take.
解题报告
本题的一大重要的条件是,Jimmy只会从A到B当且仅当B存在一条回家的路比所有从A出发回家的路都要短。所以我们去求从家出发的单源最短路径,然后使用记忆化搜索就好了。
source code
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stdbool.h>
#define MAXN 1005
#define INF 0x3f3f3f3f
int graph[MAXN][MAXN];
int n,m;
int dist[MAXN];
int total[MAXN];
void Input()
{
int i,j,k,t;
memset(graph,INF,sizeof(graph));
memset(total,-1,sizeof(total));
total[2] = 1;
for(i=1;i<=n;i++)
graph[i][i] = 0;
for(i=1;i<=m;i++){
scanf("%d %d %d",&j,&k,&t);
graph[j][k] = graph[k][j] = t;
}
}
void Minpath()
{
bool visited[MAXN];
int i,j;
for(i=1;i<=n;i++)dist[i] = graph[2][i];
memset(visited,false,sizeof(visited));
visited[2] = true;
while(1){
int temp1 = 2;
int temp2 = INF;
for(j=1;j<=n;j++){
if(!visited[j] && dist[j]<temp2){
temp2 = dist[j];
temp1 = j;
}
}
if(visited[temp1])break;
visited[temp1] = true;
for(j=1;j<=n;j++){
if(temp2+graph[temp1][j]<dist[j]){
dist[j] = graph[temp1][j]+temp2;
}
}
}
//for(i=1;i<=n;i++)printf("%d\n",dist[i]);
}
int Dfs(int index)
{
int i,sum=0;
if(total[index]>=0)return total[index];
for(i=1;i<=n;i++){
if(graph[index][i]<INF&&dist[index]>dist[i]&&i!=index)sum+=Dfs(i);
}
return total[index]=sum;
}
int main()
{
freopen("input","r",stdin);
while(1){
scanf("%d",&n);
if(!n)break;
scanf("%d",&m);
Input();
Minpath();
printf("%d\n",Dfs(1));
}
}
结语
这两天,ACM/ICPC世界总决赛在泰国清迈进行,想来看算法也快一年了。而今年又有一所中国的大学第一次进入了world final。我想,好好努力吧,未来谁知道呢?不说了,要看直播去了。再次感谢我的队友,因为你们我不再羡慕任何人,任何事。