A. ∞
一句话题意
给定a、b。并求出a/b最简分数形式
解法
直接上代码
Code
#include<bits/stdc++.h>
using namespace std;
const int N = 1e4+17;
int n,a[N],b[N],pos1,pos2;
void Work(){
scanf("%d",&n);
for(int i=0;i<=n;++i){
scanf("%d",&a[i]);
if(a[i]!=0)pos1=i;
}
for(int i=0;i<=n;++i){
scanf("%d",&b[i]);
if(b[i]!=0)pos2=i;
}
if(pos1>pos2)
printf("infty\n");
else if(pos1<pos2)
printf("0 1\n");
else{
int gcd = __gcd(a[pos1],b[pos2]);
printf("%d %d\n",a[pos1]/gcd,b[pos2]/gcd);
}
}
int main(){
int T;
scanf("%d",&T);
while(T--)Work();
return 0;
}
B. lxdlam和他的迷宫
一句话题意
给定一个方型 n ∗ m n*m n∗m地图,求能否从 ( 1 , 1 ) (1,1) (1,1)走到 ( n , m ) (n,m) (n,m)
解法
深搜可能会炸,不如上广搜。
Code
#include<bits/stdc++.h>
using namespace std;
char opt;
bool maps[17][17],vis[17][17];
struct Point{
int x,y;
};
queue<Point>ready;
int cg[4][2] = {{0,1},{0,-1},{-1,0},{1,0}};
int main(){
for(int i=1;i<=10;++i){
for(int j=1;j<=10;++j){
opt = getchar();
if(opt=='.')
maps[i][j]=0;
else
maps[i][j]=1;
}
getchar();
}
ready.push((Point){1,1});
vis[1][1] = 1;
while(!ready.empty()){
Point u = ready.front();
ready.pop();
int xx,yy;
for(int i=0;i<4;++i){
xx = u.x + cg[i][0];
yy = u.y + cg[i][1];
if(xx <= 0 || xx>10)
continue;
if(yy <= 0 || yy>10)
continue;
if(!maps[xx][yy] && !vis[xx][yy]){
vis[xx][yy]=1;
ready.push((Point){xx,yy});
}
}
}
if(vis[10][10])
printf("Yes");
else
printf("No");
return 0;
}
C. cqsss and his enterprise
一句话题意
给定 a a a个棋子,两个人 A , B A,B A,B分别取, A A A每次最多取m个,B每次最多取k个,问A有没有可能取到最后一个棋子。
博弈论解答
直接套板子就好了
动态规划
假设现在有
L
L
L个棋子,假设上次
A
A
A已经取完,但
B
B
B没有取。
则利用
F
[
i
]
F[i]
F[i]表示有
i
i
i个棋子的情况下,
A
A
A能够取走最后一个。
显然当
L
−
k
>
=
1
L - k >= 1
L−k>=1
L
−
1
<
=
m
L - 1 <= m
L−1<=m
的时候可以满足
所以就直接转移就可以了
Code
#include<bits/stdc++.h>
using namespace std;
const int A = 1e5+17,AA = 1e4+17;
int n,m,kk,F[A],tr[A];
int main(){
scanf("%d%d%d",&n,&m,&kk);
for(int i=1;i<=m;++i)
F[i]=1;
if(m>=kk)
for(int i=m+1;i<=AA;++i)
for(int j=i-m-1;j<=i-kk-1;++j)
if(F[i] = F[j]) break;
for(int i=1,a;i<=n;++i){
scanf("%d",&a);
if(!F[a]){
printf("No");
return 0;
}
}
printf("Yes");
return 0;
}
D. Songer 的排兵布阵
一句话题意
求 a < = b < = c a<=b<=c a<=b<=c 且满足 a 2 + b 2 = c 2 + 1 a^2 + b^2 = c^2 + 1 a2+b2=c2+1的个数。
无题解。
E. EdChu与炸金花
一句话题意
写几个
i
f
if
if和
f
o
r
for
for。
再写个排序。
Code
None
F. Ramen and his faculty
题意
给定n个元素,组成k个集合。
且集合满足的关系:
S
i
+
1
⊆
S
i
S_{i+1} \subseteq S_i
Si+1⊆Si
求合法的方案数。
解答
对 n,k打表就完了。。。
Code
#include<bits/stdc++.h>
using namespace std;
const long long MOD = 1e9+7;
const int N = 1e3+17;
int k,n;
long long Pow(int a,int b){
long long ans =1;
for(int i=1;i<=b;++i)
ans = (ans*a)%MOD;
return ans%MOD;
}
int main(){
scanf("%d%d",&k,&n);
printf("%lld",Pow(k+1,n));
return 0;
}
G. LFhase与他的学术文章
一句话题意
就是个缩点DP模板题
Code
#include<bits/stdc++.h>
using namespace std;
const int N = 500017,M = 500017;
int n,m,tails,fr[N],nxt[M],to[M];
int Fr[N],Sum[N],Nxt[M],To[M],Tails;
void add(int f,int t){
to[++tails] = t;
nxt[tails] = fr[f];
fr[f] = tails;
}
void Add(int f,int t){
To[++Tails] = t;
Nxt[Tails] = Fr[f];
Fr[f] = Tails;
}
int a[N],S,P;
bool Ed[N];
int tim,dfn[N],low[N],cols[N],col;
stack<int>dff;
void DFS(int u,int fa){
dfn[u] = low[u] = ++tim;
dff.push(u);
for(int zj=fr[u],v;zj;zj=nxt[zj]){
if((v=to[zj])==fa) continue;
if(!dfn[v])
DFS(v,u),low[u]=min(low[u],low[v]);
if(!cols[v])
low[u] = min(low[u],dfn[v]);
}
if(low[u]==dfn[u]){
col++;
int q;
do{
q = dff.top();
dff.pop();
cols[q] = col;
Sum[col] += a[q];
}while(q!=u);
}
}
int comin[N];
void Remap(){
for(int i=1;i<=n;++i){
if(!cols[i]) continue;
for(int zj=fr[i];zj;zj=nxt[zj]){
if(!cols[to[zj]]) continue;
if(cols[i] == cols[to[zj]])
continue;
Add(cols[i],cols[to[zj]]);
comin[cols[to[zj]]]++;
}
}
}
int Mx[N];bool vis[N];
queue<int>ready;
void DP(){
for(int i=1;i<=col;++i)
Mx[i] = Sum[i];
ready.push(cols[S]);vis[cols[S]]=1;
while(!ready.empty()){
int q = ready.front();
ready.pop();vis[q] = 1;
for(int zj=Fr[q],v;zj;zj=Nxt[zj]){
if(vis[v=To[zj]])continue;
Mx[v] = max(Mx[v],Sum[v]+Mx[q]);
if((--comin[v])==0)
ready.push(v);
}
}
}
int DD[N];
int main(){
scanf("%d%d",&n,&m);
for(int i=1,p1,p2;i<=m;++i){
scanf("%d%d",&p1,&p2);
add(p1,p2);
}
for(int i=1;i<=n;++i)
scanf("%d",&a[i]);
scanf("%d%d",&S,&P);
DFS(S,0);
Remap();
DP();
int ans = 0;
for(int i=1,x;i<=P;++i){
scanf("%d",&x);
Ed[x] = 1;
ans = max(ans,Mx[cols[x]]);
}
printf("%d",ans);
return 0;
}
H. Songer and his army
一句话题意
排队等待,求最小的总等待时间。
解法
从小往大排序做贪心,证明可以参考交换法。
Code
#include<bits/stdc++.h>
using namespace std;
const int N = 1e3+17;
int n,m,t[N];
long long ans;
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i)
scanf("%d",&t[i]);
sort(t+1,t+n+1);
for(int i=1;i<=n;++i){
ans += (n-i+1)*t[i];
}
if(ans >= m)
printf("Yes");
else
printf("No");
return 0;
}