比赛入口
A - 俄罗斯方块(模拟)
用数组c[] 表示每一列能放方块的最大值(从下往上放的,所以从大到小),然后就是ctrl c + ctrl v的复制粘贴模拟。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <queue>
#include <map>
#include <vector>
#include <algorithm>
typedef long long ll ;
using namespace std ;
const int N = 20 ;
const ll mod=1e9+7 ;
int g[N][N] ,c[N];
int main(){
int n; scanf("%d",&n) ;
for(int i=1 ; i<=10 ; ++i) c[i]=10 ;
for(int i=1 ; i<=n; ++i){
int x,y; scanf("%d%d",&x,&y) ;
if(x==1){
int j=min(c[y],c[y+1]) ;
g[j][y]=1 , g[j][y+1]=1 ;
g[j-1][y]=1 , g[j-1][y+1]=1 ;
c[y]=min(c[y],j-2) , c[y+1]=min(c[y+1],j-2) ;
}
else if(x==2){
int j=min(c[y],min(c[y+1],c[y+2])) ;
g[j][y]=1 , g[j][y+1]=1 , g[j][y+2]=1 ;
g[j-1][y]=1 ;
c[y]=min(c[y],j-2) ;
c[y+1]=min(c[y+1],j-1) , c[y+2]=min(c[y+2],j-1) ;
}
else if(x==3){
int j=min(min(c[y],c[y+1]),min(c[y+2],c[y+3])) ;
g[j][y]=1 , g[j][y+1]=1 , g[j][y+2]=1 , g[j][y+3]=1 ;
c[y]=min(c[y],j-1) , c[y+1]=min(c[y+1],j-1) ;
c[y+2]=min(c[y+2],j-1) , c[y+3]=min(c[y+3],j-1) ;
}
else if(x==4){
int j=min(c[y],min(c[y+1],c[y+2])) ;
g[j][y]=1 , g[j][y+1]=1 , g[j][y+2]=1 ;
g[j-1][y+1]=1 ;
c[y]=min(c[y],j-1) , c[y+1]=min(c[y+1],j-2) ;
c[y+2]=min(c[y+2],j-1) ;
}
}
for(int i=1 ; i<=10 ; ++i){
for(int j=1 ; j<=10 ; ++j)
printf("%d ",g[i][j]) ;
printf("\n") ;
}
return 0 ;
}
B - 签到题
真 签到题哈哈哈哈哈哈
C - 港口(差分)*
如果全部重量相同,那么数组的差分应该是全为0,所以要想办法把差分数组变为0,差分数组 [i,j] 加1 就是 ++subi , --subj+1 ; 减1 就是 --subi , ++subj+1 ,剩下没有为0的就单独变成0 ;
例如:数组7 9 6 5 ,差分数组为 2 -3 -1 ,
那么可以[1,2]减2,差分数组变成: 0 -1 -1 ,现在没有正数了就单独一个变成0 ,需要两次操作,总共4次操作。
所以就是差分数组的正数和 还有 负数和 两者取最大值即可。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
typedef long long ll ;
using namespace std ;
const int N = 1e5+10 ;
ll w[N],sub[N] ;
int main(){
int n; scanf("%d",&n) ;
for(int i=1 ; i<=n ; ++i) scanf("%lld",&w[i]) , sub[i]=w[i]-w[i-1] ;
ll x=0 , y=0 ;
for(int i=2 ; i<=n ; ++i){
if(sub[i]>0) x+=sub[i] ;
else y += -sub[i] ;
}
printf ("%lld\n",max(x,y)) ;
return 0 ;
}
E - 简单的线性代数(数论)- 找规律蒙的
emmmmm这道题,一看以为要用矩阵乘积,但是k却特别大,而且过的人也特别多,然后就看样例猜了一下。。。。。,除了对角线是1-x,其他全部取反。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
typedef long long ll ;
using namespace std ;
const int N = 1010 ;
const ll mod=1e9+7 ;
int a[N][N] ;
int main(){
int n,k; scanf("%d%d",&n,&k) ;
for(int i=1 ; i<=n ; ++i){
for(int j=1 ; j<=n ; ++j){
scanf("%d",&a[i][j]) ;
if(i==j) a[i][j] = 1-a[i][j] ;
else a[i][j] = -a[i][j] ;
}
}
for(int i=1 ; i<=n ; ++i){
for(int j=1 ; j<=n ; ++j)
printf("%d ",a[i][j]) ;
printf("\n") ;
}
return 0 ;
}
G 数位操作1(模拟)
将n从9->2一直除,结果n=1则将因子排序后输出,如果n<10 那么最小值应该是1n , 其实是道挺简单的题,但是自己粗心忘记考虑n<10的情况(后来考虑到又想错了),然后就WA好几次 TAT
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <queue>
#include <map>
#include <vector>
#include <algorithm>
typedef long long ll ;
using namespace std ;
const int N = 20 ;
const ll mod=1e9+7 ;
vector<ll> ans ;
int main(){
ll n ;
while(~scanf("%lld",&n)){
ans.clear() ;
if(n<10){
printf("1%lld\n",n) ;
continue ;
}
for(ll i=9 ; i>=2 ; --i){
while(n%i==0) ans.push_back(i),n/=i;
}
if(n==1&&ans.size()>1){
sort(ans.begin(),ans.end()) ;
for(int i=0 ; i<ans.size() ; ++i) printf("%lld",ans[i]) ;
printf("\n") ;
}
else printf("-1\n") ;
}
return 0 ;
}
K - 签个到(思维)- 忘记特判
题解: 先求每个数增加和减少的最大值,然后增加的最大值减去数组的最小值和减少的最大值加上数组的最大值即可,注意n=1时要特判。
哇!气死了气死了气死了,n==1的时候没有特判然后一直WA,哭了,而且还不能在前面特判完return 0(会段错误)┭┮﹏┭┮
#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
typedef long long ll ;
using namespace std ;
const int N = 1e6+10 ;
const ll INF=1e9+7 ;
ll a[N] ;
int main(){
ll n,m ; scanf("%lld%lld",&n,&m) ;
ll mx=-INF,amx=-INF,mn=-INF,amn=INF ;
for(int i=1 ; i<=n ; ++i){
scanf("%lld",&a[i]) ;
if(a[i]>amx) amx=a[i] ;
if(a[i]<amn) amn=a[i] ;
mx=max(mx,a[i]+(ll)i*m) ;
mn=max(mn,-a[i]+(ll)i*m) ;
}
if(n==1) printf("0\n") ; //特判
else printf ("%lld\n",max(mx-amn,mn+amx)) ;
return 0 ;
}