每次比完赛,必写总结博客,已经成为一种习惯,既是对比赛中所要掌握的东西的一个回顾,基础夯实,同时又能对自身一些知识本应该掌握运用却未能完全掌握的查缺补漏,激励前进!
想起Qzone,也是背后默默支持的能记点东西的地方,故这几天总结持续更新。。。
比赛链接:​​​http://acm.hust.edu.cn/vjudge/contest/view.action?cid=71326#overview​​​ 题目来源:福州大学 oj:​​http://acm.fzu.edu.cn/
​  A - 大王叫我来巡山呐

Crawling in process... Crawling failed1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

Submit ​​ Status​​​ ​​ Practice​​​ ​​ FZU 2167​

Description

  大师兄在取得真经后,每天详读经书,认真完成读书笔记,理论联系实际,不断提高实践能力。假设大师兄开始修炼的第一天是星期一,至今已经修炼了N天,那么有多少天是星期六或者星期日,大师兄还在修炼呢?

Input

  每组输入数据包含一个整数N(0<N<100,000)。

Output

  对每组输入数据,输出一行,仅包含一个整数,表示这N天中是星期六或者星期日的天数。

Sample Input

567121314

Sample Output
0 1 2 2 3 4 
思路:
水题,不解释~~

代码:

<span style="font-size:14px;"> #include <iostream>
#include <stdio.h>
using namespace std;
int main()
{
int n,b;
while(cin>>n)
{
b=n/7*2;
if(n%7==6)
b++;
cout<<b<<endl;
} return 0;}</span>

B - 防守阵地 I

Crawling in process... Crawling failed3000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

Submit ​​ Status​​​ ​​ Practice​​​ ​​ FZU 2168​

Description

部队中共有N个士兵,每个士兵有各自的能力指数Xi,在一次演练中,指挥部确定了M个需要防守的地点,按重要程度从低到高排序,依次以数字1到M标注每个地点的重要程度,指挥部将选择M个士兵依次进入指定地点进行防守任务,能力指数为X的士兵防守重要程度为Y的地点将得到X*Y的参考指数。现在士兵们排成一排,请你选择出连续的M个士兵依次参加防守,使得总的参考指数值最大。

Input

输入包含多组数据。

输入第一行有两个整数N,M(1<=N<=1000000,1<=M<=1000),第二行N个整数表示每个士兵对应的能力指数Xi(1<=Xi<=1000)。

对于30%的数据1<=M<=N<=1000。

Output

输出一个整数,为最大的参考指数总和。

Sample Input

5 3
2 1 3 1 4

Sample Output
 17
思路:
刚看到题,第一感觉可以暴力循环试一下,,然后认真的读了几遍题,开始敲题,敲着敲着,突然发现没思路了。。囧。。 
 喝了一口水,(哈其实是咽了咽口水~~囧)
然后又敲了一边:
发现,思路逐渐在大脑里有点清晰 :
 a+b+c+d+e    sum[5]

b+c+d+e      sum[5]-sum[1]

用sum[n]代表前n项和,s[n]代表前n个sum和

a+2b+3c+4d+5e = 5*sum[5]-(sum[2]+sum[3]+sum[4])

= 5*sum[5] - (s[2]-s[1]+s[3]-s[2]+s[4]-s[3])

= 5*sum[5] - (s[4]-s[2])

 

可以推导出

ans = m*sum[i]-(s[i-1]-s[i-1-m])
当然可以从后面往前推:

dp[k]=dp[k-1]-ans[k-1]+x[i]*m;

ans[k-1]是m个数求和。 

(不知道自己在说神马~~),当然一时不能完全理解的,非常正常,此题,zj也是最后做出来。。慢慢理解~~

代码:

<span style="font-size:14px;">#include <math.h>
#include <queue>
#include <map>
#include <set>
#include <deque>
#include <vector>
#include <stack>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <iomanip>
#include <iostream>
#include <algorithm>
#define Max(a,b) a>b?a:b
using namespace std;
const int N= 1000005;
int aa[N],bb[N];
int main()
{
int n,m,a,b,i,j,k;
while(~scanf("%d%d",&n,&m))
{
int ans=0,cnt=0;
aa[0]=bb[0]=0;
for(i=1; i<=n; i++)
{
scanf("%d",&a);
aa[i]=aa[i-1]+a; //bb[i]=bb[i-1]+a;
bb[i]=bb[i-1]+aa[i];
}
for(i=m; i<=n; i++)
{
ans=m*aa[i]-(bb[i-1]-bb[i-1-m]);
cnt= Max(cnt,ans);
}
printf("%d\n",n<=m?aa[n]:cnt);
}
return 0;
}
</span>

C - shadow

Crawling in process... Crawling failed1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

Submit ​​ Status​​​ ​​ Practice​​​ ​​ FZU 2169​

Description

YL是shadow国的国王,shadow国有N个城市。为了节省开支,shadow国只有N-1条道路,这N-1条道路使得N个城市连通。某一年,shadow国发生了叛乱,叛军占领了多个城市,王都岌岌可危。王都为编号为1的城市,除了王都外有K个城市有YL的军队。现在这K支军队要向王都进军,并且消灭沿途经过的城市中的叛军。现给出N个城市的道路情况以及城市的叛军数量,问总共需要消灭多少叛军?

Input

第一行输入两个整数N,K,接下来输入N(1<=N<=100000)个整数Ai(0<=Ai<=10000),表示第i个城市的叛军数量。接下来输入K个大于等于1且小于等于N的整数,表示有军队的城市的编号。数据保证王都以及有军队的城市没有叛军。接下来输入N-1行,每行两个整数u、v,表示连接u和v的一条道路。每支军队只能沿着道路走,并且是其所在城市与王都之间的最短路线走。

Output

输出一行一个整数表示消灭的叛军数量。

Sample Input

4 20 3 0 03 41 22 32 4

Sample Output 3

思路:又是忧伤的最短路问题(迪杰斯特拉,,弗洛伊德,,SPFA?)

当然,此题,,没有告诉城市与城市的之间距离,(其实也没必要),可以预处理一些,因为要求的是消灭叛军的数量

,及处理每个城市记录的叛军数量, ,模板开始没照打,自己慢慢凭记忆,一点一点敲着,,,然后 一编译,,,各种错误提示!

无奈,时间有限, 虽过犹败了 (看了模板)。。。

用优先队列优化(很重要,防止超时!)一下,计算 叛军的城市个数,一个标志, 消灭一波叛军就标志减少, 直到全部消灭:

 代码:

<span style="font-size:14px;">#include <math.h>
#include <queue>
#include <map>
#include <set>
#include <deque>
#include <vector>
#include <stack>
#include <stdio.h>
#include <ctype.h
#include <string.h>
#include <stdlib.h>
#include <iomanip>
#include <iostream>
#include <algorithm>
using namespace std;
#define lowbit(a) a&-a
#define Max(a,b) a>b?a:b
#define Min(a,b) a>b?b:a
#define mem(a,b) memset(a,b,sizeof(a))
int dir[4][2]= {{1,0},{-1,0},{0,1},{0,-1}};
const double eps = 1e-6;
const double Pi = acos(-1.0);
static const int Inf= ~0U>>2;
static const int maxn=111000;
int n,m,N,K,M,ss,i,j;
int mapp[maxn];
int liter[maxn];
int result[maxn];
bool vis[maxn];
int head[maxn];
struct node
{
int va;
int na;
}
city[maxn*2];
struct node2
{
int va2;
int shadi;
} p, q;
void add(int u, int v)
{
city[ss].va=v;
city[ss].na = head[u];
head[u] = ss++;
}
int dijkstra(int x)
{
int cnt = 0;
queue<node2> Q;
p.va2 = x;
p.shadi = liter[x];
Q.push(p);
vis[x] = 1;
while (!Q.empty())
{
p = Q.front();
Q.pop();
if (1 == p.va2) cnt = p.shadi;
for (int i = head[p.va2]; i != 0; i = city[i].na)
{
int v = city[i].va;
if(vis[v]==0)
{
vis[v] = 1;
q.va2 = v;
q.shadi = p.shadi + liter[v];
Q.push(q);
}
}
}
return cnt;
}
int main()
{

while (cin>>N>>K)
{
for (i = 1; i <= N; i++)
cin>>liter[i];
for (i = 1; i <= K; i++)
cin>>result[i];
mem(vis,0),mem(head,0);
ss=1;
int P=N-1;
for(i=1; i<=P; i++)
{
int u,v;
cin>>u>>v;
add(u,v);
add(v,u);
}
int sum = 0;
for(i=1; i<=K; i++)
{
int aa=result[i];
if (vis[aa]==0)
sum+=dijkstra(aa);
}
printf("%d\n",sum);
}
return 0;
}

PS:此题可能是数据有问题,如果什么也不管,统计所有叛军的数量直接输出就能过,
也是赛后发现漏洞!!若此,比赛时也就根本用不着考虑用最短路,坑啊!</span>

when you wan to give up ,think of why you are persit until now!