今天的题是真的沙雕
第一题
【题目描述】
Yashem66学长有严重的强迫症!他完全无法忍受那些令他抓狂的东西,比如文具袋里的直尺,比如画得不规范的立方体。他总是自言自语:强人♂所难。
请写出一个程序,程序在读入立方体的三个棱长后,输出一个格式如样例的“立方体”。
【输入】
每个测试点一组测试数据,每组数据包含三个数字,表示立方体的长、宽、高分别为a,b,c。
【输出】
输出一个规定尺寸的立方体(形式如样例)。
【数据范围与约定】
对于100%的数据满足 — a,b,c<=20
(提示)把样例复制到记事本里用等宽字体看体验更佳。
这题恶心模拟。。
Code
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int a,b,c;
char s[505][505];
int main()
{
memset(s,' ',sizeof(s));
scanf("%d%d%d",&a,&b,&c);
int n=2*b+2*c+1;
int m=2*b+2*a+1;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(i+j<=2*b+1||(n-i+1)+(m-j+1)<=2*b+1)s[i][j]='.';
else
if(i%2==0)
{
if(i<=2*b)
{
if(j%2==0)s[i][j]='/';
else if(i/2>=(m-j+2)/2)s[i][j]='|';
else s[i][j]='.';
}
else
{
if(j&1)s[i][j]='|';
else if((m-j+1)/2<=b)s[i][j]='/';
else s[i][j]='.';
}
}
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(s[i][j]!=' ')continue;
if(i<=2*b)
{
if(j&1)s[i][j]='+';
else
{
if(s[i+1][j-1]=='|')s[i][j]='.';
else
{
s[i][j]='-';
}
}
}
else if(s[i-1][j]=='/'&&s[i+1][j]=='/')
{
if(s[i+1][j-1]=='|')s[i][j]='.';
else
{
s[i][j]='-';
}
}
else
{
if(j&1)s[i][j]='+';
else s[i][j]='-';
}
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
printf("%c",s[i][j]);
}
printf("\n");
}
return 0;
}
第二题
【题目描述】
Yashem66学长喜欢数独和妹子。在基友们的疯狂安利下,学长又入了16 * 16数独的大坑,对妹子日渐冷淡。而妹子不甘示弱、争风吃醋,于是便把学长做好的16 * 16数独分割成了4 * 4的16个方块后(数独术语中又称之为宫),进行如下操作若干次:任选一个宫后,使其逆时针旋转90°(一个宫可被旋转任意次)。
学长看着被搞坏的数独陷入了沉思:她至少要操作多少次呢?
【输入】
每个测试点多组测试数据,第一行一个整数T,表示共有T组测试数据。
对于每组测试数据,输入一个被学姐玩坏的16 * 16的数独,数独内元素以16进制数(既0123456789ABCDEF)表示。
【输出】
对于每组数据输出一行,表示学姐至少操作了多少次
【样例】
Input:
1
681D5A0C9FDBB2F7
0A734B62E167D9E5
5C9B73EF3C208410
F24ED18948A5CA63
39FAED5616400B74
D120C4B7CA3DEF38
7EC829A085BE6D51
B56438F129F79C2A
5C7FBC4E3D08719F
AE8B1673BF42A58D
60D3AF25619C30BE
294190D8EA57264C
C7D1B35606835EAB
AF52A1E019BE4306
8B36DC78D425F7C9
E409492FC7FA18D2
Output:
5
【数据范围与约定】
对于10%的数据满足 — T<=1,000
对于20%的数据满足 — T<=5,000
对于60%的数据满足 — T<=15,000
对于100%的数据满足 — T<=35,000
搜索。我们把每一行可能的状态列举出来,四进制,0表示不旋转,1表示转一次,以此类推
然后判断合不合法位运算就好了
具体看代码
Code
#include <bits/stdc++.h>
using namespace std;
inline char get_val(char ch) {
if('0'<=ch && ch<='9') return ch-'0';
return 10+ch-'A';
}
inline int add(int a,int b) {
if(a+b<4) return a+b;
return a+b-4;
}
#define bit(k) (1<<(k))
const int n=16;
int T;
char s[n+5][n+5];
int grid[n+5][n+5][4];
int rot[n+5][n+5], ROT[n+5];
void init() {
register int i,j,k;
for(i=0;i<n;++i) {
ROT[i]=0;
for(j=0;j<n;++j) {
rot[i][j]=0;
for(k=0;k<4;++k)
grid[i][j][k]=0;
}
}
return;
}
void calc_grid(int x,int y) {
register int i,j;
for(i=x*4;i<(x+1)*4;++i)
for(j=y*4;j<(y+1)*4;++j) {
if(i==4*x) grid[x][y][0]|=bit(s[i][j]);
if(j==4*y) grid[x][y][1]|=bit(s[i][j]);
if(i==4*x+3) grid[x][y][2]|=bit(s[i][j]);
if(j==4*y+3) grid[x][y][3]|=bit(s[i][j]);
}
return;
}
bool check_row(int r) {
int cur1=0;
for(int j=0;j<4;++j) cur1|=grid[r][j][rot[r][j]];
return (cur1==((1<<16)-1));
}
bool dfs_row(int x,int y) {
if(y==4) return check_row(x);
for(int i=0;i<4;++i) {
rot[x][y]=i;
if(dfs_row(x,y+1)) return true;
}
return false;
}
bool check_col(int c) {
int cur=0;
for(int i=0;i<4;++i) cur|=grid[i][c][(rot[i][c]+ROT[i]+1)%4];
return (cur==((1<<16)-1));
}
bool dfs_col(int x,int y) {
if(x==4) return check_col(y);
for(int i=0;i<4;i+=2) {
ROT[x]=i;
if(dfs_col(x+1,y)) return true;
}
return false;
}
void work() {
register int i,j;
init();
for(i=0;i<n;++i) {
scanf("%s",s[i]);
for(j=0;j<n;++j)
s[i][j]=get_val(s[i][j]);
}
for(i=0;i<4;++i)
for(j=0;j<4;++j)
calc_grid(i,j);
for(i=0;i<4;++i)
dfs_row(i,0);
dfs_col(0,0);
for(i=0;i<4;++i) if(ROT[i])
for(j=0;j<4;++j)
rot[i][j]+=ROT[i];
int ans1=0;
for(i=0;i<4;++i)
for(j=0;j<4;++j)
ans1+=rot[i][j]%4;
int ans2=0;
for(i=0;i<4;++i)
for(j=0;j<4;++j)
ans2+=(rot[i][j]+2)%4;
printf("%d\n",min(ans1,ans2));
return;
}
int main() {
for(scanf("%d",&T);T;T--)
work();
return 0;
}
第三题
【题目描述】
Yashem66学长作为第五期团的成员踏上了新大陆。第五期团共有n个成员,分布在大陆各处,每个成员都分别开拓了一条通往五期团其他成员位置的双向路径,且保证任何两个成员间都可互相到达。熔山龙对地脉的反复冲击使地貌变得多变,每条路径有一个初始崎岖度wei,熔山龙的冲击很可能会改变路径的崎岖度。由于学长的肝爆了,作为学长的搭档,团长交给你了一些你力所能及的任务,任务中可能是两种操作之一:
1)0 id val,将第id条路径的崎岖度改为val;
2)1 x y,询问x与y之间的崎岖度最小的路线的崎岖度(路线的崎岖度为路线上各路径的崎岖度之和)。
【输入】
输入数据的第一行包括两个整数n、m ,分别表示五期团的人数和任务的数目;接下来的n行,每行三个整数u、v、wei,表示有一条崎岖度为wei的从u到v的路径;接下来的m行,每行三个整数op、x、y,描述任务的内容。
【输出】
对于每个op=1的任务,输出一行一个整数作为答案。
【样例1】
Input1:
5 5
1 2 3
2 3 5
2 4 5
2 5 1
4 3 3
0 1 5
1 3 2
1 5 4
0 5 4
1 5 1
Output1:
5
6
6
【样例2】
Input2:
5 3
1 2 3
1 3 2
3 4 4
4 5 5
2 5 5
0 1 3
0 4 1
1 1 4
Output2:
6
【数据范围与约定】
对于40%的数据满足 — n,m<=1,000
对于100%的数据满足 — n,m<=200,000 , 路径权值<=100,000
裸基环树剖,代码长度6k
考场上三个半点都给你也打不完。。
等等!貌似这道题可以用更简单的方法解决
我们来一个dfs序,用树状数组维护就好了~
还是
具体看代码
Code
#include<cstdio>
#include<iostream>
#define lowbit(x) x&(-x)
using namespace std;
int n,m;
int f[2000005];
int fst[2000005];
int nxt[4000005];
int k[4000005];
int v[4000005];
int edge;
void add(int x,int y,int val)
{
edge++;
nxt[edge]=fst[x];
fst[x]=edge;
v[edge]=y;
k[edge]=val;
}
inline int find(int x)
{
return f[x]=(f[x]==x?x:find(f[x]));
}
int xx[2000005];
int yy[2000005];
int ww[2000005];
int deep[2000005];
int dfn[2000005];
int tt[2000005];
int fa[300005][30];
int cnt;
long long sum[2000005];
void ad(int x,int val)
{
while(x<=n)
{
sum[x]+=val;
x+=lowbit(x);
}
}
long long query(int x)
{
long long ans=0;
while(x)
{
ans+=sum[x];
x-=lowbit(x);
}
return ans;
}
void dfs(int x,int pre,int val)
{
dfn[x]=++cnt;
fa[x][0]=pre;
deep[x]=deep[pre]+1;
ad(cnt,val);
for(int i=fst[x];i;i=nxt[i])
{
//cout<<x<<" "<<v[i]<<" "<<pre<<endl;
if(v[i]==pre)continue;
else
{
dfs(v[i],x,k[i]);
}
}
tt[x]=cnt;
ad(cnt+1,-val);
}
int lca(int x,int y)
{
if(deep[x]<deep[y])swap(x,y);
for(int i=25;i>=0;i--)
{
if(deep[fa[x][i]]>=deep[y])x=fa[x][i];
}
if(x==y)return x;
for(int i=25;i>=0;i--)
{
if(fa[x][i]!=fa[y][i])
{
x=fa[x][i];
y=fa[y][i];
}
}
return fa[x][0];
}
long long dist(int x,int y)
{
int vv=lca(x,y);
return query(dfn[x])+query(dfn[y])-2*query(dfn[vv]);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
f[i]=i;
}
int ll,rr,vl,id;
for(int i=1;i<=n;i++)
{
int x,y,val;
scanf("%d%d%d",&x,&y,&val);
int fx=find(x);
int fy=find(y);
if(fx==fy)
{
ll=x;
rr=y;
vl=val;
id=i;
}
else
{
add(x,y,val);
add(y,x,val);
f[fx]=fy;
}
xx[i]=x;
yy[i]=y;
ww[i]=val;
}
dfs(1,0,0);
for(int j=1;j<=25;j++)
{
for(int i=1;i<=n;i++)
{
fa[i][j]=fa[fa[i][j-1]][j-1];
}
}
for(int i=1;i<=m;i++)
{
int op,y,x;
scanf("%d%d%d",&op,&x,&y);
if(op==0)
{
if(id==x)vl=y;
else
{
int u=(fa[xx[x]][0]==yy[x]?xx[x]:yy[x]);
ad(dfn[u],-ww[x]+y);
ad(tt[u]+1,-y+ww[x]);
ww[x]=y;
}
}
else
{
long long ans=dist(x,y);
ans=min(ans,dist(x,ll)+dist(y,rr)+vl);
ans=min(ans,dist(x,rr)+dist(y,ll)+vl);
printf("%lld\n",ans);
}
}
return 0;
}
顺便吐槽一下,沙雕出题人直接从hdu扒题,样例都一样,无语。。