这次考的是
A
t
C
o
d
e
r
AtCoder
AtCoder的题 发挥不是很好
用洛谷当题面了 还能方便点
A
直接七天一求和就行
#include<bits/stdc++.h>
#define reg register
using namespace std;
inline void read(int &x){
int s=0,w=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){s=(s<<3)+(s<<1)+(ch&15);ch=getchar();}
x=s*w;
}
int n,a,x;
int main(){
read(n);
for(int i=1;i<=n;i++){
x=0;
for(int j=1;j<=7;j++)read(a),x+=a;
printf("%d ",x);
}
puts("");
}
B
就 100 100 100个字符串 暴力两个两个判断即可
#include<bits/stdc++.h>
#define reg register
using namespace std;
inline void read(int &x){
int s=0,w=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){s=(s<<3)+(s<<1)+(ch&15);ch=getchar();}
x=s*w;
}
char s[110][110],ss[110];
int n,l[110];
bool pd(char str[],int len){
for(int l=0,r=len-1;l<=r;l++,r--){
if(str[l]!=str[r])return false;
}
return true;
}
int main(){
read(n);
for(int i=1;i<=n;i++)cin.getline(s[i],sizeof s[i]),l[i]=strlen(s[i]);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(j==i)continue;
for(int k=0;k<l[i];k++)ss[k]=s[i][k];
for(int k=0;k<l[j];k++)ss[k+l[i]]=s[j][k];
if(pd(ss,l[i]+l[j])){
puts("Yes");
return 0;
}
}
}
puts("No");
}
C
因为拼接之后最大的图形也只有 10 × 10 10×10 10×10,所以直接将 A , B A,B A,B暴力移动到所有位置,一一判断,时间复杂度 O ( 1 0 6 ) O(10^6) O(106)
#include<bits/stdc++.h>
#define reg register
#define N 100
using namespace std;
inline void read(int &x){
int s=0,w=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){s=(s<<3)+(s<<1)+(ch&15);ch=getchar();}
x=s*w;
}
int ha,wa,hb,wb,hx,wx,a[N][N],b[N][N],x[N][N];
bool check(int ax, int ay, int bx, int by){
for(int i=1;i<=ha;i++){
for(int j=1;j<=wa;j++){
if(!((i+ax>0&&i+ax<=hx)&&(j+ay>0&&j+ay<=wx))&&a[i][j])return false;
if(((i+ax>0&&i+ax<=hx)&&(j+ay>0&&j+ay<=wx))&&a[i][j])
if(!x[i+ax][j+ay])return false;
}
}
for(int i=1;i<=hb;i++){
for(int j=1;j<=wb;j++){
if(!((i+bx>0&&i+bx<=hx)&&(j+by>0&&j+by<=wx))&&b[i][j])return false;
if(((i+bx>0&&i+bx<=hx)&&(j+by>0&&j+by<=wx))&&b[i][j])
if(!x[i+bx][j+by])return false;
}
}
for(int i=1;i<=hx;i++)
for(int j=1;j<=wx;j++)
if(x[i][j]&&!a[i-ax][j-ay]&&!b[i-bx][j-by])return false;
return true;
}
int main(){
read(ha),read(wa);
for(reg int i=1;i<=ha;i++){
for(reg int j=1;j<=wa;j++){
char chr=getchar();
while(chr!='.'&&chr!='#')chr=getchar();
if(chr=='#')a[i][j]=1;
}
}
read(hb),read(wb);
for(reg int i=1;i<=hb;i++){
for(reg int j=1;j<=wb;j++){
char chr=getchar();
while(chr!='.'&&chr!='#')chr=getchar();
if(chr=='#')b[i][j]=1;
}
}
read(hx),read(wx);
for(reg int i=1;i<=hx;i++){
for(reg int j=1;j<=wx;j++){
char chr=getchar();
while(chr!='.'&&chr!='#')chr=getchar();
if(chr=='#')x[i][j]=1;
}
}
for(int ai=-10;ai<=10;ai++){
for(int aj=-10;aj<=10;aj++){
for(int bi=-10;bi<=10;bi++){
for(int bj=-10;bj<=10;bj++){
if(check(ai,aj,bi,bj)){
puts("Yes");
return 0;
}
}
}
}
}
puts("No");
}
D
模拟,把两个括号之间没有括号的子字符串删除即可,考场上因为这题题面没看懂浪费了一个小时时间
#include<bits/stdc++.h>
#define reg register
using namespace std;
inline void read(int &x){
int s=0,w=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){s=(s<<3)+(s<<1)+(ch&15);ch=getchar();}
x=s*w;
}
stack<char> s;
stack<char> ans;
int n,lst,eps[200002],nxt[200002];
char chr;
int main(){
read(n);
for(int i=1;i<=n;i++){
chr=getchar();
while(chr!='('&&chr!=')'&&(chr<'a'||chr>'z'))chr=getchar();
if(chr=='('){
nxt[i]=lst;lst=i;
s.push(chr);
}
else if(chr>='a'&&chr<='z')s.push(chr);
else if(chr==')'){
if(lst){
for(int j=lst;j<=i-1-eps[lst]&&!s.empty();j++){
s.pop();
}
eps[nxt[lst]]+=(i-lst+1);
lst=nxt[lst];
}
else{
s.push(chr);
lst=0;
}
}
}
while(!s.empty()){
ans.push(s.top());
s.pop();
}
while(!ans.empty()){
putchar(ans.top());
ans.pop();
}
puts("");
}
E
d
p
,
dp,
dp,设
d
p
[
i
]
[
0
]
dp[i][0]
dp[i][0]表示第
i
i
i个人与第一个人的数不相同,并且相邻两人的也不相同的方案数,
d
p
[
i
]
[
1
]
dp[i][1]
dp[i][1]表示只有第
i
i
i个人与第一个人的数相同,其他都不相同的方案数
首先考虑
d
p
[
i
]
[
1
]
,
dp[i][1],
dp[i][1],第
i
i
i个人与第一个人可以看成一个人,所以
d
p
[
i
]
[
1
]
=
d
p
[
i
−
1
]
[
0
]
dp[i][1]=dp[i-1][0]
dp[i][1]=dp[i−1][0]
再考虑
d
p
[
i
]
[
0
]
,
dp[i][0],
dp[i][0],对第
i
−
1
i-1
i−1个人分类讨论,如果与第一个人相同,那第
i
i
i个人有
m
−
1
m-1
m−1种情况,去掉第
i
i
i个人,就变成了
d
p
[
i
−
1
]
[
1
]
dp[i-1][1]
dp[i−1][1]
如果与第一个人不同,那么第
i
i
i个人有
m
−
2
m-2
m−2种情况,去掉第
i
i
i个人,就变成了
d
p
[
i
−
1
]
[
0
]
dp[i-1][0]
dp[i−1][0]
所以转移式为
d
p
[
i
]
[
0
]
=
(
m
−
1
)
d
p
[
i
−
1
]
[
1
]
+
(
m
−
2
)
d
p
[
i
−
1
]
[
0
]
dp[i][0]=(m-1)dp[i-1][1]+(m-2)dp[i-1][0]
dp[i][0]=(m−1)dp[i−1][1]+(m−2)dp[i−1][0]
d
p
[
i
]
[
1
]
=
d
p
[
i
−
1
]
[
1
]
dp[i][1]=dp[i-1][1]
dp[i][1]=dp[i−1][1]
最后输出
d
p
[
n
]
[
0
]
dp[n][0]
dp[n][0]即可。
#include<bits/stdc++.h>
#define reg register
#define N int(1e6+10)
using namespace std;
typedef long long ll;
const ll mod=998244353;
ll qpow(ll x, ll y){
ll re=1;
while(y){
if(y&1)(re*=x)%=mod;
(x*=x)%=mod,y>>=1;
}
return re;
}
ll n,m,dp[N][2];
int main(){
cin>>n>>m;
dp[1][1]=m;
for(int i=2;i<=n;i++){
dp[i][0]=((m-1)*dp[i-1][1]%mod+(m-2)*dp[i-1][0]%mod)%mod;
dp[i][1]=dp[i-1][0];
}
cout<<dp[n][0]<<endl;
}
F
利用最短路的思想,每次把中毒的点距离设为 0 0 0,并更新相邻的点的 d i s dis dis数组,并放进小根堆中,每一天把堆中距离小于 x x x的拿出来更新,距离设为 0 0 0,并更新相邻的点,同时记录感染时间即可,因为每个点会被第一次设距离,第二次中毒更新,因此最多会遍历两次,时间复杂度就是最短路的时间复杂度,即为 O ( n l o g m ) O(nlog_m) O(nlogm)
#include<bits/stdc++.h>
#define reg register
#define N 300030
using namespace std;
typedef long long ll;
inline void read(int &x){
int s=0,w=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){s=(s<<3)+(s<<1)+(ch&15);ch=getchar();}
x=s*w;
}
struct edges{
int to,val,nxt;
}edge[N<<1];
struct node{
int id;
ll d;
node(int x, ll y){
id=x,d=y;
}
bool operator <(const node &p) const {
return p.d<d;
}
};
int n,u,v,w,m,k,x,t,pnt,head[N],cnt,vis[N],newin[N];
ll dis[N];
inline void addedge(int u, int v, int w){
edge[++cnt].to=v,edge[cnt].nxt=head[u],head[u]=cnt,edge[cnt].val=w;
}
inline void superadd(int u, int v, int w){
addedge(u,v,w),addedge(v,u,w);
}
int main(){
read(n),read(m);
for(reg int i=1;i<=m;i++)read(u),read(v),read(w),superadd(u,v,w);
read(k);
memset(dis,0xf,sizeof dis);
memset(vis,-1,sizeof vis);
priority_queue<node> q;
for(int j=1;j<=k;j++){
read(u);
vis[u]=0;dis[u]=0LL;
q.push(node(u,0LL));
for(int i=head[u];i;i=edge[i].nxt){
int vv=edge[i].to;
if(dis[vv]>edge[i].val){
dis[vv]=edge[i].val;
q.push(node(vv,dis[vv]));
}
}
}
read(t);
for(int ii=1;ii<=t;ii++){
pnt=0;
read(x);
while(!q.empty()){
node now=q.top();
if(dis[now.id]>x)break;
q.pop();
if(dis[now.id]!=now.d||vis[now.id]!=-1)continue;
vis[now.id]=ii;newin[++pnt]=now.id;
for(int i=head[now.id];i;i=edge[i].nxt){
int vv=edge[i].to;
if(dis[vv]>dis[now.id]+edge[i].val){
dis[vv]=dis[now.id]+edge[i].val;
q.push(node(vv,dis[vv]));
}
}
}
for(int j=1;j<=pnt;j++){
for(int i=head[newin[j]];i;i=edge[i].nxt){
int vv=edge[i].to;
if(dis[vv]>edge[i].val){
dis[vv]=edge[i].val;
q.push(node(vv,dis[vv]));
}
}
}
}
for(int i=1;i<=n;i++)printf("%d\n",vis[i]);
}