NUPT大二队员淘汰赛1
比赛链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=101409#overview
密码:acm1248
![](http://acm.fzu.edu.cn/image/problem.gif)
Accept: 380 Submit: 710
Time Limit: 1000 mSec Memory Limit : 32768 KB
Problem Description
![](http://acm.fzu.edu.cn/image/Problem/980012.jpg)
Input
Output
Sample Input
9
001@11@10
001111110
001111110
001@22@10
0012@2110
221222011
@@11@112@
2211111@2
000000111
Sample Output
Source
2010年全国大学生程序设计邀请赛(福州)
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n;
char mp[20][20];
int dx[8] = {0, 0, 1, 1, 1, -1, -1, -1};
int dy[8] = {1, -1, 0, 1, -1, 0, 1, -1};
void DFS(int x, int y)
{
mp[x][y] = '#';
for(int i = 0; i < 8; i++)
{
int xx = x + dx[i];
int yy = y + dy[i];
if(xx >= 1 && yy >= 1 && xx <= n && yy <= n && mp[xx][yy] != '#' && mp[xx][yy] != '@')
{
if(mp[xx][yy] == '0')
DFS(xx, yy);
else
mp[xx][yy] = '#';
}
}
return;
}
int main()
{
int T;
scanf("%d", &T);
for(int ca = 1; ca <= T; ca++)
{
int ans = 0;
scanf("%d", &n);
for(int i = 1; i <= n; i++)
scanf("%s", mp[i] + 1);
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
{
if(mp[i][j] == '0')
{
DFS(i, j);
ans ++;
}
}
}
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
if(mp[i][j] != '#' && mp[i][j] != '@')
ans ++;
printf("Case %d: %d\n", ca, ans);
}
}
matrix
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 588 Accepted Submission(s): 339
For each cases, first come 2 integers, n,m(1≤n≤1000,1≤m≤1000)
N+m is an odd number.
Then follows n lines with m numbers ai,j(1≤ai≤100)
2 3 1 2 3 2 2 1 2 3 2 2 1 1 2 4
4 8
#include <cstdio>
#include <cstring>
#include <algorithm>
#define ll long long
using namespace std;
int const MAX = 1e3 + 5;
ll dp[MAX][MAX], a[MAX][MAX];
int main()
{
int n, m;
while(scanf("%d %d", &n, &m) != EOF)
{
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
scanf("%I64d", &a[i][j]);
memset(dp, 0, sizeof(dp));
dp[1][2] = a[1][2] * a[1][1];
dp[2][1] = a[2][1] * a[1][1];
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= m; j++)
{
if((i + j) & 1)
{
if(j > 2 && dp[i][j - 2])
{
if(dp[i][j])
dp[i][j] = min(dp[i][j], dp[i][j - 2] + a[i][j] * a[i][j - 1]);
else
dp[i][j] = dp[i][j - 2] + a[i][j] * a[i][j - 1];
}
if(i > 2 && dp[i - 2][j])
{
if(dp[i][j])
dp[i][j] = min(dp[i][j], dp[i - 2][j] + a[i][j] * a[i - 1][j]);
else
dp[i][j] = dp[i - 2][j] + a[i][j] * a[i - 1][j];
}
if(i > 1 && j > 1 && dp[i - 1][j - 1])
{
if(dp[i][j])
dp[i][j] = min(dp[i][j], dp[i - 1][j - 1] + min(a[i][j - 1] * a[i][j], a[i - 1][j] * a[i][j]));
else
dp[i][j] = dp[i - 1][j - 1] + min(a[i][j - 1] * a[i][j], a[i - 1][j] * a[i][j]);
}
}
}
}
printf("%I64d\n", dp[n][m]);
}
}
Accept: 296 Submit: 1115
Time Limit: 3000 mSec Memory Limit : 32768 KB
Problem Description
部队中总共有N个士兵,每个士兵有各自的能力指数Xi,在一次演练中,指挥部确定了M个需要防守的地点,指挥部将选择M个士兵依次进入指定地点进行防守任务,获得的参考指数即为M个士兵的能力之和。随着时间的推移,指挥部将下达Q个指令来替换M个进行防守的士兵们,每个参加完防守任务的士兵由于疲惫等原因能力指数将下降1。现在士兵们排成一排,请你计算出每次进行防守的士兵的参考指数。
Input
输入包含多组数据。
输入第一行有两个整数N,M,Q(1<=N<=100000,1<=M<=1000,1<=Q<=100000),第二行N个整数表示每个士兵对应的能力指数Xi(1<=Xi<=1000)。
接下来Q行,每行一个整数X,表示在原始队列中以X为起始的M个士兵替换之前的士兵进行防守。(1<=X<=N-M+1)
对于30%的数据1<=M,N,Q<=1000。
Output
输出Q行,每行一个整数,为每次指令执行之后进行防守的士兵参考指数。
Sample Input
2 1 3 1 4
1
2
3
Sample Output
3
5
#include <cstdio>
#include <cstring>
#include <algorithm>
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
using namespace std;
int const MAX = 1e5 + 5;
int sum[MAX << 2], lazy[MAX << 2];
int n, m, q;
void PushUp(int rt)
{
sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
}
void PushDown(int ln, int rn, int rt)
{
if(lazy[rt])
{
sum[rt << 1] -= lazy[rt] * ln;
sum[rt << 1 | 1] -= lazy[rt] * rn;
lazy[rt << 1] += lazy[rt];
lazy[rt << 1 | 1] += lazy[rt];
lazy[rt] = 0;
}
}
void Build(int l, int r, int rt)
{
lazy[rt] = 0;
if(l == r)
{
scanf("%d", &sum[rt]);
return;
}
int mid = (l + r) >> 1;
Build(lson);
Build(rson);
PushUp(rt);
}
void Update(int L, int R, int c, int l, int r, int rt)
{
if(L <= l && r <= R)
{
lazy[rt] += 1;
sum[rt] += -(r - l + 1);
return;
}
int mid = (l + r) >> 1;
PushDown(mid - l + 1, r - mid, rt);
if(L <= mid)
Update(L, R, c, lson);
if(mid < R)
Update(L, R, c, rson);
PushUp(rt);
}
int Query(int L, int R, int l, int r, int rt)
{
if(L <= l && r <= R)
return sum[rt];
int mid = (l + r) >> 1, ans = 0;
PushDown(mid - l + 1, r - mid, rt);
if(L <= mid)
ans += Query(L, R, lson);
if(mid < R)
ans += Query(L, R, rson);
return ans;
}
int main()
{
while(scanf("%d %d %d", &n, &m, &q) != EOF)
{
Build(1, n, 1);
while(q --)
{
int x;
scanf("%d", &x);
printf("%d\n", Query(x, x + m - 1, 1, n, 1));
Update(x, x + m - 1, -1, 1, n, 1);
}
}
}
Time Limit: 5000MS | Memory Limit: 65536K | |
Total Submissions: 10135 | Accepted: 2347 |
Description
Mr.Dog was fired by his company. In order to support his family, he must find a new job as soon as possible. Nowadays, It's hard to have a job, since there are swelling numbers of the unemployed. So some companies often use hard tests for their recruitment.
The test is like this: starting from a source-city, you may pass through some directed roads to reach another city. Each time you reach a city, you can earn some profit or pay some fee, Let this process continue until you reach a target-city. The boss will compute the expense you spent for your trip and the profit you have just obtained. Finally, he will decide whether you can be hired.
In order to get the job, Mr.Dog managed to obtain the knowledge of the net profit Vi of all cities he may reach (a negative Vi indicates that money is spent rather than gained) and the connection between cities. A city with no roads leading to it is a source-city and a city with no roads leading to other cities is a target-city. The mission of Mr.Dog is to start from a source-city and choose a route leading to a target-city through which he can get the maximum profit.
Input
The first line of each test case contains 2 integers n and m(1 ≤ n ≤ 100000, 0 ≤ m ≤ 1000000) indicating the number of cities and roads.
The next n lines each contain a single integer. The ith line describes the net profit of the city i, Vi (0 ≤ |Vi| ≤ 20000)
The next m lines each contain two integers x, y indicating that there is a road leads from city x to city y. It is guaranteed that each road appears exactly once, and there is no way to return to a previous city.
Output
Sample Input
6 5 1 2 2 3 3 4 1 2 1 3 2 4 3 4 5 6
Sample Output
7
Hint
![](https://i-blog.csdnimg.cn/blog_migrate/9ddd58e4c7b9e60e4fecd5018ba68c55.gif)
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
int const MAX = 1e5 + 5;
int const INF = 2147483640;
int n, m;
int dp[MAX], val[MAX], ind[MAX];
vector <int> vt[MAX];
int DFS(int x)
{
if(dp[x])
return dp[x];
int sz = vt[x].size();
if(sz == 0)
return val[x];
int tmp = -INF;
for(int i = 0; i < sz; i++)
{
int u = vt[x][i];
tmp = max(tmp, val[x] + DFS(u));
}
return dp[x] = tmp;
}
int main()
{
while(scanf("%d %d", &n, &m) != EOF)
{
for(int i = 1; i <= n; i++)
vt[i].clear();
memset(ind, 0, sizeof(ind));
memset(dp, 0, sizeof(dp));
for(int i = 1; i <= n; i++)
scanf("%d", &val[i]);
for(int i = 0; i < m; i++)
{
int u, v;
scanf("%d %d", &u, &v);
vt[u].push_back(v);
ind[v]++;
}
int ans = -INF;
for(int i = 1; i <= n; i++)
if(!ind[i])
ans = max(ans, DFS(i));
printf("%d\n", ans);
}
}
«Next please», — the princess called and cast an estimating glance at the next groom.The princess intends to choose the most worthy groom, this is, the richest one. Whenever she sees a groom who is more rich than each of the previous ones, she says a measured «Oh...». Whenever the groom is richer than all previous ones added together, she exclaims «Wow!» (no «Oh...» in this case). At the sight of the first groom the princess stays calm and says nothing.
The fortune of each groom is described with an integer between 1 and 50000. You know that during the day the princess saw n grooms, said «Oh...» exactly a times and exclaimed «Wow!» exactly b times. Your task is to output a sequence of n integers t1, t2, ..., tn, where tidescribes the fortune of i-th groom. If several sequences are possible, output any of them. If no sequence exists that would satisfy all the requirements, output a single number -1.
The only line of input data contains three integer numbers n, a and b (1 ≤ n ≤ 100, 0 ≤ a, b ≤ 15, n > a + b), separated with single spaces.
Output any sequence of integers t1, t2, ..., tn, where ti (1 ≤ ti ≤ 50000) is the fortune of i-th groom, that satisfies the given constraints. If no sequence exists that would satisfy all the requirements, output a single number -1.
10 2 3
5 1 3 6 16 35 46 4 200 99
5 0 0
10 10 6 6 5
Let's have a closer look at the answer for the first sample test.
- The princess said «Oh...» (highlighted in bold): 5 1 3 6 16 35 46 4 200 99.
- The princess exclaimed «Wow!» (highlighted in bold): 5 1 3 6 16 35 46 4 200 99.
题目大意:构造一个n个数的序列,满足公主叫了a次Oh和b次Wow,公主遇到一个数字,这个数字比前面的所有数字都大时她会叫Oh,公主遇到一个数字,这个数字比前面所有数字的和都大时,公主会叫Wow,叫Wow的话就不叫Oh了,构造的数字不能大于5万,如果不存在则输出-1
题目分析:先明确一点,前两个数字,如果第二个比第一个大,这种情况公主会叫Wow,这题构造方法不唯一,最简单的应该是二进制法,举个例子比如b等于3这时候我们就可以构造0001,0010,0100,1000,0001+0010 = 0011正好比0100小1,同理0001+0010+0100 = 0111,正好比1000小1,又b最大为15,所以构造b的值最大到2^15=32768,然后构造a就方便了,直接往后依次加1即可,构造完a,b,剩下来的数全都等于构造a时的最后一个数即可
#include <cstdio>
int ans[105];
int main()
{
int a, b, n, cur = 1;
scanf("%d %d %d", &n, &a, &b);
ans[1] = 1;
for(int i = 2; i <= n; i++)
{
if(b)
{
ans[i] = 1 << (i - 1);
b --;
}
else if(a && i > 2)
{
ans[i] = ans[i - 1] + 1;
a --;
}
else
ans[i] = ans[i - 1];
}
if(a || b)
printf("-1\n");
else
{
for(int i = 1; i < n; i++)
printf("%d ",ans[i]);
printf("%d\n", ans[n]);
}
}
1256: 天朝的单行道
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 277 Solved: 90
[ Submit][ Status][ Web Board]
Description
Input
Output
Sample Input
2 1
1 2
2 1
2 1
2 0
Sample Output
0
1
-1
Source
题目分析:原来的路权值为0,然后建一条反向边权值为1,相当于如果这条反向边在你的最短路上,那就表示这条边要建,然后从1-n用SPFA跑一个最短路,dist[n]就是答案,本题用二维数组存貌似会炸
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
int const MAX = 5005;
int const INF = 1 << 30;
int n, m, dis[MAX];
bool vis[MAX];
struct EGDE
{
int u, v, w;
}e[MAX << 1];
struct NODE
{
int v, w;
NODE(int vv, int ww)
{
v = vv;
w = ww;
}
};
vector <NODE> vt[MAX];
void SPFA(int v0)
{
queue <int> q;
for(int i = 1; i <= n; i++)
dis[i] = INF;
memset(vis, false, sizeof(vis));
dis[v0] = 0;
vis[v0] = true;
q.push(v0);
while(!q.empty())
{
int u = q.front();
q.pop();
vis[u] = false;
int sz = vt[u].size();
for(int i = 0; i < sz; i++)
{
int v = vt[u][i].v;
int w = vt[u][i].w;
if(dis[v] > dis[u] + w)
{
dis[v] = dis[u] + w;
if(!vis[v])
{
vis[v] = true;
q.push(v);
}
}
}
}
return;
}
int main()
{
while(scanf("%d %d", &n, &m) != EOF)
{
for(int i = 0; i <= n; i++)
vt[i].clear();
for(int i = 0; i < m; i++)
scanf("%d %d", &e[i].u, &e[i].v);
for(int i = 0; i < m; i++)
{
vt[e[i].u].push_back(NODE(e[i].v, 0));
vt[e[i].v].push_back(NODE(e[i].u, 1));
}
SPFA(1);
if(dis[n] == INF)
printf("-1\n");
else
printf("%d\n", dis[n]);
}
}
How many integers can you find
Time Limit: 12000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 6047 Accepted Submission(s): 1734
12 2 2 3
7
题目分析:很基础的容斥题,有个坑点,集合中可能有0,如果有0的话,直接把0去掉,还可以加个小特判,如果有1的话直接输出n就行了,注意这里容斥不是把数字直接相乘,因为它们不一定互质,所以算的是数字间的最小公倍数,举个简单例子:
25 26 8
答案如果直接用24 / 6 + 24 / 8 - 24 / (6 * 8)得到的是7,显然答案是6,因为24没有被容斥掉,所以我们要拿两个数的最小公倍数去容斥
#include <cstdio>
#include <cstring>
#include <algorithm>
#define ll long long
using namespace std;
int a[25], b[25];
ll ans;
int n, m, cnt;
ll gcd(ll a, ll b)
{
return b ? gcd(b, a % b) : a;
}
ll lcm(int a, int b)
{
return (ll) a * b / gcd(a, b);
}
void DFS(int idx, ll cur, int sgin)
{
for(int i = idx; i < cnt; i++)
{
ll tmp = lcm(cur, (ll)b[i]);
ans += (ll) sgin * (n / tmp);
DFS(i + 1, tmp, -sgin);
}
}
int main()
{
while(scanf("%d %d", &n, &m) != EOF)
{
n --;
cnt = 0;
bool flag = false;
for(int i = 0; i < m; i++)
{
scanf("%d", &a[i]);
if(a[i] != 0)
b[cnt ++] = a[i];
if(a[i] == 1)
flag = true;
}
if(flag)
{
printf("%d\n", n);
continue;
}
sort(b, b + cnt);
ans = 0;
DFS(0, 1, 1);
printf("%I64d\n", ans);
}
}