132 - A - 胡乱走的和尚
题意:
对于这样一个矩阵,和尚从1出发,经过一系列上下左右乱走问最后在哪,如果走出去就完蛋啦。
模拟一下就好啦,左右差n,上下差1。如果和尚走出去了直接break出来
#include <cstdio>
#define F(_i,_u) for(int _i=0;_i<(_u);_i++)
int dic[205][2]={0};
//小和尚往哪走(LRDU)
char o[5];
int main(){
//向量
dic['D'][1]=dic['R'][0]=1;dic['U'][1]=dic['L'][0]=-1;
//t:case总数
//n,M:题目给出
//x,y:当前坐标
//oo:小和尚这次走了几步
//flag:小和尚完蛋了吗?
int t,n,M,x,y,oo,flag=1;
for(scanf("%d",&t);t--;flag=1){
scanf("%d%d",&n,&M);
x=y=1;
F(m,M){
scanf("%s%d",o,&oo);
if(flag){
x+=dic[o[0]][0]*oo;y+=dic[o[0]][1]*oo;
if(x<1||y<1||x>n||y>n)flag=0;
}
}
if(flag)printf("%d\n",x*n+y-n);
else puts("WanQuanGaoBuDong!");
}
}
137 - B - NeXT
求比给定字符串大的字符串中最小的字符串。
设字符串
S=c1c2...cncn+1
S
=
c
1
c
2
.
.
.
c
n
c
n
+
1
其中
cn+1=‘∖0′
c
n
+
1
=
‘
∖
0
′
我们知道靠前的字符要尽可能地小,那么从后往前找,第一个非降序字符就是我们需要完成交换的目标字符
ci
c
i
(若未找到则
i=0
i
=
0
跃出字符串下标)。
再次从后往前找,找到第一个大于
ci
c
i
的字符
cj
c
j
然后把
ci
c
i
与
cj
c
j
交换,输出
c1...ci−1cjcn...cj+1cicj−1...ci+1
c
1
.
.
.
c
i
−
1
c
j
c
n
.
.
.
c
j
+
1
c
i
c
j
−
1
.
.
.
c
i
+
1
易证明这个字符串一定是满足题意的字符串。
证明:
c1...ci−1
c
1
.
.
.
c
i
−
1
是相同前缀,无法增加,那么只考虑之后的字符串。
cj
c
j
是后续字符串中大于c_i中最小的字符。那么
c1...ci−1cj
c
1
.
.
.
c
i
−
1
c
j
是大于
c1...ci−1ci
c
1
.
.
.
c
i
−
1
c
i
最小的字符串,现在只用输出之后的字符串最小字典序即可。我们知道由于我们的算法后续字符串恰好是最大字典序,那么逆序输出即可。
#include <iostream>
#include <string>
using namespace std;
string str;
int main(){
ios::sync_with_stdio(false);
int len,cur,cur2,t;
while(cin>>str){
len=str.size();
cur=len-2;
while(cur>=0&&str[cur]>=str[cur+1])cur--;
if(cur==-1)cout<<"What?"<<endl;
else{
cur2=len-1;
while(cur2>cur&&str[cur2]<=str[cur])cur2--;
t=str[cur];str[cur]=str[cur2];str[cur2]=t;
for(int i=0;i<=cur;i++)cout<<str[i];
for(int i=len-1;i>cur;i--)cout<<str[i];
cout<<endl;
}
}
}
133 - C - 蛇形填数
题意:
观察
分奇偶行填数就行了,这个蛇形填数比书上的简单多了=w =
#include <cstdio>
#define F(_i,_u) for(int _i=0;_i<(_u);_i++)
int main(){
int n,cnt;
while(~scanf("%d",&n)){
cnt=0;
F(i,n){
if(i&1){
cnt+=n;
F(i,n)printf("%4d",cnt--);
cnt+=n;
}
else F(i,n)printf("%4d",++cnt);
puts("");
}
puts("");
}
}
136 - D - 满天繁星
给定一组坐标(x,y,z),给定一组查询求对应(x,y,z)是否存在。
因为,我们把x,y,z右偏50,然后*128(实际上64就足够了)得到哈希值,然后就很容易了。
#include <cstdio>
#include <map>
#define F(_i,_u) for(int _i=0;_i<(_u);_i++)
using namespace std;
//map构造的hash表
map<int,bool> hoshi;
int main(){
int n,x,y,z;
while(~scanf("%d",&n)){
hoshi.clear();
F(i,n){
scanf("%d%d%d",&x,&y,&z);
//不知道为什么hash内联以后会报错,干脆直接复制粘贴到对应地方算了。
hoshi[((((x+50)<<7)+y+50)<<7)+z+50]=1;
}
scanf("%d",&n);
F(i,n){
scanf("%d%d%d",&x,&y,&z);
puts(hoshi[((((x+50)<<7)+y+50)<<7)+z+50]?"YES":"NO");
}
}
}
139 - E - Easy Triangle
题意:求n阶杨辉三角
递推方程:
#include <cstdio>
//杨辉三角C(n-1,m-1)
long long c[51][51]={0};
int main(){
//直接求出50阶杨辉三角
c[1][1]=1;
for(int i=2;i<=50;i++)for(int j=1;j<=i;j++)c[i][j]=c[i-1][j]+c[i-1][j-1];
int n;
while(~scanf("%d",&n)){
for(int i=0;++i<=n;printf("%d\n",c[i][i]))for(int j=1;j<i;j++)printf("%lld ",c[i][j]);
}
}
138 - F - Water
题意:n个人等待接水,问n个人等待的时间最小是多少。
sort(A) s o r t ( A ) 后, ans=∑n1Si=∑n1∑i1Aj a n s = ∑ 1 n S i = ∑ 1 n ∑ 1 i A j ,因为根据排序不等式 Si S i 是对应长度 i i <script type="math/tex" id="MathJax-Element-3317">i</script>最小的序列和。
#include <cstdio>
#include <algorithm>
#define F(_i,_u) for(int _i=0;_i<(_u);_i++)
using namespace std;
int a[10005];
int main(){
int n;long long ans,s;
while(~scanf("%d",&n)){
ans=s=0;
F(i,n)scanf("%d",&a[i]);
sort(a,a+n);
F(i,n){
s+=a[i];
ans+=s;
}
printf("%lld\n",ans);
}
}
134 - G - Chem Is A Third Try!!
给你首先给你n个数组长度,然后接下来n行,每行为对应长度的数组,有M次操作,每次操作交换a和b两行数组,求最终数组序列。
由于行内数据不会进行交换,我们把每行看作一个字符串,然后就简单很多了!
#include <iostream>
#include <cstdio>
#include <string>
#define F(_i,_u) for(int _i=0;_i<(_u);_i++)
#define FF(_i,_l,_r) for(int _i=_l;_i<=(_r);_i++)
using namespace std;
//行下标
int sorti[1005];
//行数组
string s[1005];
int main(){
ios::sync_with_stdio(false);
int n,M,t,a,b;
while(cin>>n>>M){
//get掉n,M后面的\n
getline(cin,s[0]);
//s[0]是长度那一行
FF(i,0,n)getline(cin,s[i]);
FF(i,1,n)sorti[i]=i;
F(m,M){
cin>>a>>b;
t=sorti[a];sorti[a]=sorti[b];sorti[b]=t;
}
FF(i,1,n)cout<<s[sorti[i]]<<endl;
}
}