排名:http://acm.szu.edu.cn/wiki/index.php/Special:JudgeContestRank
可能这次比赛对平时不太玩的同学有点残忍。
题目难度总体比去年(H47-H50,H53,H57-H61)高一点,少了一个特别的水题。导致本次1题获奖,然后三等奖没有发完,fb也出得很慢,25分钟,WA两次。
不过蛮高兴的事,蛮多人坚持到最后了,ACM需要坚持。
本次的最高题数是5题,有点可惜。
不算酱油的,19个人过题,有点悲剧。
但还是祝贺一下本次获奖的同学。
同时也感谢一下学生会的支持。
废话不说,解题先
Problem A. Magic Matrix
标签:**题 模拟题
题意:2^k*2^k的方阵分四块,然后重组成2^(k+1)*2^(k-1)的矩阵,直到变成一行。
解法:写个函数move(i,j,ii,jj,size)直接搞应该行,动态内存应该不会超。
Problem B. Simple Count
标签:*题 简单大数
题意:找出[0,m]之间个位是n(0<=n<9)的整数的个数
解法:看最后一位,大于等于n的,不要最后一位然后+1就好,
小于n就直接不要最后一位输出,数据没有前导0,应该不难。
Problem C. Travel Problem
标签:**题 dfs、bfs、并查集
题意:有n个景点,景点有value,景点之间有road,可以在景点之间相互到达,
第一次可以任选一个点,问能获得的value的最大值。
解法:上面三种做法都可以,就找出每个联通分量,然后找最大值即可。
Problem D. Divide apple
标签:**题 排序+索引排序
题意:给n个苹果,按大到小依次分m个人,问最后一个人得到的苹果的序号,序号要求升序。
解法:struct{int size, num,ismine; }这样存就好,第一次按size排序,标ismine(1,0),
然后按ismine,num排序就好。
Problem E. Game
标签:*题 想法题
题意:一个有n个cells的box,每个里面有一些小球,可以间隔m从前往后移动小球,
问第一个状态能不能移到第二个。
解法:本来没有从前往后的,那样间隔求和就好。这个加上从前往后比较就好啦。
Problem F. A Strange Tree
标签:***题 树dp
题意:一棵无向树,每个节点有一些值,拿了这个与他相连都不能拿,问能拿到的最大值。
解法:dfs,等到该节点变黑(出栈)的时候拿孩子孙子节点更新当前节点,
得到以该点为根的最值,然后dfs(1)就是结果。也可以动态更新。也可以先建孩子兄弟树搞。
Problem G. A simple problem with square pattern
标签:****题 线段树 成段更新,点查询
题意:n个3*3的矩阵,m次操作(旋转,翻转或者查询某个节点的矩阵)
解法:线段树,注意到旋转和翻转是有序的,把翻转往后拖,可加点延迟。
这类问题目前好像没有通用解法,方向有:懒操作(统一成一个操作,或者一个操作往后拖),状态压缩。
Problem H. Chinese Zodiac
标签:***题 状态压缩+spfa
题意:12种动物,有n中魔法,每种魔法可以从一个动物状态转到另一个状态,价值是第二个状态的动物数*魔法自身价值。
解法:01标记各种动物在与不在,则有2^12种状态,然后每种魔法当做一条边,spfa之。
Problem I. ABC
标签:**题 bfs
题意:给个类似迷宫的东西,然后有三个人,他们可以到处跑,问最小的会面步数。
解法:对三个人bfs,记录各点最小步数,然后查看vis为3的点的最小值就好。
我只搞了自己的题以及测了益望的题,可能有错,请指正。
后记:感觉蛮好,大一的蛮给力,当然也有悲剧的事以及可惜的事,大家继续加油哈!
然后谢谢两位队员!这套题大家还是花了不少时间的,然后,出题不容易啊!!
最后贴几个代码:
简单题就不贴了
C:Travel
#include <cstdio>
#include <cstring>
#include <cassert>
#define N 1050
int val[N], vis[N], mat[N][N];
int n, max_val, num_val;
void dfs(int x){
vis[x]=1; num_val+=val[x];
for(int i=1; i<=n; ++i) {
if(mat[x][i] && !vis[i])
dfs(i);
}
}
int main()
{
int m, i, u, v, cas=1;
freopen("in1.txt","r", stdin);
freopen("ou1.txt","w", stdout);
while(scanf("%d%d", &m, &n) && (m+n)){
assert(1<=n && n<=1000);
assert(0<=m && m<=N*N);
memset(mat, 0, sizeof(mat));
memset(vis, 0, sizeof(vis));
for(i=1; i<=n; ++i) {
scanf("%d", &val[i]);
assert(1<=val[i] && val[i]<=1000);
}
for(i=0; i<m; ++i) {
scanf("%d%d", &u, &v);
assert(1<=u && u<=n);
assert(1<=v && v<=n);
mat[u][v]=mat[v][u]=1;
}
max_val=0;
for(i=1; i<=n; ++i){
if(!vis[i]){
num_val=0; dfs(i);
if(max_val<num_val) max_val=num_val;
}
}
printf("Case %d:\n%d\n", cas++, max_val);
}
return 0;
}
I:ABC
#include <cstdio>
#include <cstring>
#include <cassert>
#include <cmath>
#include <queue>
#include <iostream>
using namespace std;
#define N 150
#define inf (0x7fffffff)
char mat[N][N], vis[N][N];
struct { int v, x;}ans[N][N];
struct info{ int v, x, y;};
int dx[]={0, 0, 1, -1};
int dy[]={1, -1, 0, 0};
int n;
inline int isok(int x, int y){
return (0<=x&&x<n && 0<=y&&y<n && !vis[x][y] && mat[x][y]!='#');
}
void bfs(int x, int y){
info of, nf;
int i;
queue<info> q;
of.v=0; of.x=x; of.y=y;
q.push(of); vis[of.x][of.y]=1;
while(!q.empty()){
of=q.front();
q.pop();
ans[of.x][of.y].v++;
ans[of.x][of.y].x+=of.v;
for(i=0; i<4; ++i){
nf.x=of.x+dx[i];
nf.y=of.y+dy[i];
nf.v=of.v+1;
if(isok(nf.x, nf.y)) {
q.push(nf); vis[nf.x][nf.y]=1;
}
}
}
}
int main()
{
int t, i, j;
int ax, ay, bx, by, cx, cy;
scanf("%d", &t);
assert(1<=t && t<=100);
while(t--) {
scanf("%d", &n);
assert(2<=n && n<=100);
getchar();
for(i=0; i<n; ++i) gets(mat[i]);
ax=ay=bx=by=cx=cy=-1;
for(i=0; i<n; ++i) {
for(j=0; j<n; ++j) {
if(mat[i][j]=='#' || mat[i][j]=='.') ;
else if(mat[i][j]=='A') {
assert(ax==-1 && ay==-1);
ax=i; ay=j;
}
else if(mat[i][j]=='B') {
assert(bx==-1 && by==-1);
bx=i; by=j;
}
else if(mat[i][j]=='C') {
assert(cx==-1 && cy==-1);
cx=i; cy=j;
}
else assert(0>1); // other? wrong
}
}
assert(ax!=-1 && ay!=-1);
assert(bx!=-1 && by!=-1);
assert(cx!=-1 && cy!=-1);
memset(ans, 0, sizeof(ans));
memset(vis, 0, sizeof(vis));
bfs(ax, ay);
memset(vis, 0, sizeof(vis));
bfs(bx, by);
memset(vis, 0, sizeof(vis));
bfs(cx, cy);
int res=inf;
for(i=0; i<n; ++i) {
for(j=0; j<n; ++j) {
assert(0<=ans[i][j].v && ans[i][j].v<=3);
if(ans[i][j].v==3 && res>ans[i][j].x)
res=ans[i][j].x;
}
}
printf("%d\n", res==inf?-1:res);
}
return 0;
}
F:Strange Tree
#include <cstdio>
#include <cstring>
#include <cassert>
#include <cmath>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
#define max(a, b) (a>b?a:b)
#define N 100000
vector<int> m[N]; // mat
int s[N], ss[N], d[N], v[N], a[N];
// son grandson dp vis data
void dfs(int r){
d[r]=s[r]=ss[r]=0;
v[r]=1; // 0 white 1 grey 2 black
for(int i=0; i<m[r].size(); ++i){
if(!v[m[r][i]]) dfs(m[r][i]);
}
for(i=0; i<m[r].size(); ++i)
{
if(v[m[r][i]]==2) {
s[r]+=d[m[r][i]];
for(int j=0; j<m[m[r][i]].size(); ++j) {
ss[r]+=d[m[m[r][i]][j]];
}
}
}
v[r]=2;
d[r]=max(s[r],ss[r]+a[r]);
}
int main()
{
int t, n, i;
scanf("%d", &t);
assert(2<=t && t<=100);
while(t--) {
memset(v, 0, sizeof(v));
memset(a, 0, sizeof(a));
for(i=0; i<N; ++i) m[i].clear();
scanf("%d", &n);
assert(2<=n && n<=10000);
for(i=1; i<=n; ++i) {
scanf("%d", &a[i]);
assert(a[i]<100);
}
int u, v;
for(i=1; i<n; ++i) {
scanf("%d%d", &u, &v);
assert(1<=u && u<=n);
assert(1<=v && v<=n);
m[u].push_back(v);
m[v].push_back(u);
}
dfs(1);
printf("%d\n", d[1]);
}
return 0;
}
H: Chinese Zodiac
#include <cstdio>
#include <cstring>
#include <cassert>
#include <vector>
#include <stack>
#include <iostream>
using namespace std;
#define LL(x) (1<<(x))
#define N (1<<12)
#define inf (0x7ffffff)
struct edge{
int t, v;
};
vector<edge> mat[N];
stack<int> mst;
int shor[N], ins[N], cas=1;
inline void init() {
for(int i=0; i<N; ++i) {
ins[i]=0;
shor[i]=inf;
mat[i].clear();
}
}
inline void input() {
edge tmp;
int i, j, m, es, ee, ev, f, x;
scanf("%d", &m);
for(i=0; i<m; ++i){
scanf("%d%d%d", &es, &ee, &ev);
f=tmp.t=tmp.v=0;
for(j=0; j<es; ++j){
scanf("%d", &x);
f+=LL(x-1);
}
for(j=0; j<ee; ++j){
scanf("%d", &x);
tmp.t+=LL(x-1);
}
tmp.v=ev*ee;
mat[f].push_back(tmp);
// printf("%d %d %d\n", f, tmp.t, tmp.v);
}
}
inline void solve(){
int u, v, i;
while(!mst.empty()) mst.pop();
mst.push(0); ins[0]=1; shor[0]=0;
while(!mst.empty()){
u=mst.top(); mst.pop();
ins[u]=0;
for(i=0; i<mat[u].size(); ++i){
v=mat[u][i].t;
if(shor[v]>shor[u]+mat[u][i].v) {
shor[v]=shor[u]+mat[u][i].v;
if(!ins[v]) {
mst.push(v); ins[v]=1;
}
}
}
}
printf("Case %d:\n%d\n", cas++, shor[4095]==inf?-1:shor[4095]);
}
int main()
{
int t;
freopen("ou5.txt","w", stdout);
freopen("in5.txt","r", stdin);
scanf("%d", &t);
while(t--){
init();
input();
solve();
}
return 0;
}
G:A Simple problem with square pattern
#include <stdio.h>
#include <string.h>
#include <assert.h>
#define N 50050
#define LL L, m, c<<1
#define RR m+1, R, c<<1|1
#define swap(a,b) a^=b^=a^=b
/*
trans
4 1 <=> 3 4
4 2 <=> 2 4
4 3 <=> 1 4
*/
char mt[N][5][5];// matrix
int rt[N<<2]={0}, ft[N<<2]={0};
// rotate reflect
void rot(int x);
void ref(int x);
void update(int c, int x);
void build(int L, int R, int c);
void pushDown(int L, int R, int c);
void ques(int p, int L, int R, int c);
void insert(int l, int r, int v, int L, int R, int c);
int main()
{
int n, q, a, b, c;
scanf("%d%d", &n, &q);
assert(1<=n && n<=N);
assert(1<=q && q<=N<<1);
build(1, n, 1);
while(q--){
char ch[2];
scanf("%s", ch);
if(*ch=='C') {
scanf("%d%d%d", &a, &b, &c);
assert(1<=a && a<=N);
assert(1<=b && b<=N);
assert(1<=c && c<=4);
assert(a<=b);
insert(a, b, c, 1, n, 1);
}
else if(*ch=='Q') {
scanf("%d", &a);
assert(1<=a && a<=N);
ques(a, 1, n, 1);
}
else assert(0>1);
}
return 0;
}
// clock 90
void rot(int x){
int i, j;
for(i=0; i<3; ++i){
for(j=0; j<3; ++j){
mt[0][i][j]=mt[x][i][j];
}
}
for(i=0; i<3; ++i){
for(j=0; j<3; ++j){
mt[x][i][j]=mt[0][2-j][i];
}
}
}
// left right
void ref(int x){
for(int i=0; i<3; ++i){
swap(mt[x][i][0], mt[x][i][2]);
}
}
// operating
void update(int c, int x){
rt[c]%=4; while(rt[c]--) rot(x);
while(ft[c]--) ref(x);
rt[c]=ft[c]=0;
}
// seg build
void build(int L, int R, int c)
{
if(L==R) {
for(int i=0; i<3; ++i)
scanf("%s", mt[L][i]);
return;
}
int m=(L+R)>>1;
build(LL);
build(RR);
}
// pushDown just once
void pushDown(int L, int R, int c){
int m=(L+R)>>1;
rt[c]%=4;
if(rt[c]){
insert(L, m, rt[c], LL);
insert(m+1, R, rt[c], RR);
}
if(ft[c]){
insert(L, m, 4, LL);
insert(m+1, R, 4, RR);
}
rt[c]=ft[c]=0;
}
// seg insert
void insert(int l, int r, int v, int L, int R, int c)
{
if(l<=L && R<=r){
if(v==1||v==2||v==3) rt[c]+=ft[c]?(4-v):v;
else if(v=4) ft[c]=ft[c]?0:1;
else assert(0>1);
return;
}
pushDown(L, R, c);
int m=(L+R)>>1;
if(l<=m) insert(l, r, v, LL);
if(r>m) insert(l, r, v, RR);
}
// point value
void ques(int p, int L, int R, int c)
{
if(L==R) {
update(c, L);
for(int i=0; i<3; ++i)
puts(mt[L][i]);
return;
}
pushDown(L, R, c);
int m=(L+R)>>1;
if(p<=m) ques(p, LL);
else ques(p, RR);
}