A题:
枚举每个sum,i代表n,j代表m,即求出sg函数
注意:要用bitset不能用bool不然会超时
#include<iostream>
#include<string>
#include <bits/stdc++.h>
using namespace std;
const int N = 5005;
bitset<N> F[N];
void pre(){
for(int sum=0;sum<=10000;sum++){
for(int i=0,j=sum-i;i<=5000&&j>=0;i++,j--){
if(!F[i][j]){
for(int k=1;i+k<=5000;k++)
for(int l=0;j+k*l<=5000;l++)
F[i+k][j+k*l]=true;
for(int k=1;j+k<=5000;k++)
for(int l=0;i+k*l<=5000;l++)
F[i+k*l][j+k]=true;
}
}
}
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
pre();
int T;
cin>>T;
while(T--){
int n,m;
cin>>n>>m;
puts(F[n][m] ? "Alice" : "Bob");
}
return 0;
}
B题:
就是找相似三角形
#include<iostream>
#include<cstring>
#include<string>
#include<cmath>
using namespace std;
#define ll long long
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
double r,a,b,h;
cin>>r>>a>>b>>h;
if(2*r<=b){
cout<<"Drop"<<endl;
}
else{
double d1=(a-b)/2;
double d2=sqrt(h*h+d1*d1);
double x=r*d2/h;
double d3=a/2-x;
double d4=d3/d1*h;
double ans=h-d4;
cout<<"Stuck"<<endl;
printf("%.10lf\n",ans);
}
return 0;
}
D题:
也是一道水题,找出一行中连续0的个数,若大于m则结果加上大于m的个数
#include<iostream>
#include<cstring>
#include<string>
using namespace std;
#define ll long long
const int N = 2050;
int n,m;
int a[N][N],b[N];
string str1[N],str2;
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>m;
for(int i=0;i<n;i++){
cin>>str1[i];
}
ll ans=0;
cin>>str2;
for(int i=0;i<n;i++){
int tmp=0;
for(int j=0;j<n;j++){
if(str1[i][j]=='0')tmp++;
if(str1[i][j]!='0'){
if(tmp>=m){
ans+=(tmp-m+1);
}
tmp=0;
}
}
if(tmp){
if(tmp>=m){
ans+=(tmp-m+1);
}
tmp=0;
}
}
cout<<ans<<endl;
return 0;
}
E题:
BFS和模拟.
题目大意:给你一个n*m的地图,从左上角开始,走到右下角,路上有各种管子,你可以随意翻转它们,输出的时候如果不能到达那就输出NO,否则输出YES,接下来就是路径和翻转管子的角度.
思路:虽然管子有6种,但是只需要分成两种来分析,一种是拐弯的,一种是不能拐弯的,不能拐弯的保持原来的方向,拐弯的则要进行判断.
#include<bits/stdc++.h>
#define LL long long
#define dl double
#define Pi pair<int,int>
#define SZ(a) ((int)a.size())
using namespace std;
const int N = 1005;
int T;
int n,m;
int a[N][N],b[N][N];
struct node{
int x,y,fro;
node(){}
node(int a,int b,int c){
x = a;y = b;fro = c;
}
};
//记录每个结构体前面的结构体
//即记录这一步前的一步的x,y,fro和状态.f[][][4]最后一个[4]代表的是状态意思是:
//up->0 right->1 down->2 left->3
node f[N][N][4];//up->0 right->1 down->2 left->3
queue<node>Q;
void ins(int x,int y,int fro,node k){
//当下一部没有被遍历过时
if(f[x][y][fro].x == -1){
Q.emplace(x,y,fro);
f[x][y][fro] = k;
}
}
//初始化
void init(){
for(int i = 0;i <= n + 1;i++)
for(int j = 0;j <= m + 1;j++)
for(int k = 0;k < 4;k++)
f[i][j][k] = node(-1,-1,-1);
f[1][1][0] = node(0,0,0);
Q.emplace(1,1,0);//从(1,1)开始,方向为向上
}
void bfs(){
init();
while(!Q.empty()){
auto now=Q.front(); Q.pop();
auto [x,y,fro] = now;//x=now.x , y=now.y , fro=now.fro
if(x < 1 || x > n || y < 1 || y > m)continue;
//分为两种情况一种是管子是弯的(0~3)
if(a[x][y] <= 3){
//当这一步的状态是向左或者向右时,下一步能扩展向上和向下
if(fro & 1){
//向上
ins(x - 1,y,2,now);
//向下
ins(x + 1,y,0,now);
}
//当这一步的状态是向上或者向下时,下一步能扩展向左和向右
else {
//向左
ins(x,y - 1,1,now);
//向右
ins(x,y + 1,3,now);
}
}
//一种的管子是直的(4~5),不管是什么情况都会保持以前的状态
else {
if(fro == 0)ins(x + 1,y,fro,now);
if(fro == 2)ins(x - 1,y,fro,now);
if(fro == 1)ins(x,y - 1,fro,now);
if(fro == 3)ins(x,y + 1,fro,now);
}
}
int id=0;
//没有走到达终点的情况
if(f[n + 1][m][id].x == -1){cout << "NO\n";return ;}
//以下为能走到终点的情况
cout << "YES\n";
//从最后一个状态开始往前递归放进ans中
node now(n + 1,m,id);
vector<vector<int>>ans;
while(now.x != 1 || now.y != 1){
auto [x,y,fro] = f[now.x][now.y][now.fro];
vector<int>tmp;
tmp.clear();tmp.push_back(0);tmp.push_back(x);
tmp.push_back(y);ans.push_back(tmp);
//角度判断
int deg = 0;
//管子为直时
if(fro == now.fro){
//fro为奇数时说明上一步为左右,那么下一步如果为上下的话角度旋转就为90
if((fro % 2 == 1) && a[x][y] == 5)deg = 90;
//fro为偶数时说明上一步为上下,那么下一步如果为左右的话角度旋转就为90
if((fro % 2 == 0) && a[x][y] == 4)deg = 90;
}
//管子为弯时
else {
int ned = 0;
//下一步为上的话判断上一步是否为右,是的话那么ned=2,否则ned=3
if(now.fro == 0)ned = (fro == 1 ? 2 : 3);
//略
if(now.fro == 2)ned = (fro == 1 ? 1 : 0);
if(now.fro == 1)ned = (fro == 0 ? 0 : 3);
if(now.fro == 3)ned = (fro == 0 ? 1 : 2);
deg = (ned - a[x][y] + 4) % 4 * 90;
}
tmp.clear();
tmp.push_back(1);
tmp.push_back(deg);
tmp.push_back(x);
tmp.push_back(y);
ans.push_back(tmp);
now = f[now.x][now.y][now.fro];//迭代,上一步等于下一步
}
memset(b,0,sizeof(b));
//对ans里面储存的数据进行输出
for(int i = SZ(ans) - 1;i >= 0;i--)
if(ans[i][0] == 1){
ans[i][1] = (ans[i][1] - b[ans[i][2]][ans[i][3]] + 360) % 360;
b[ans[i][2]][ans[i][3]] = (b[ans[i][2]][ans[i][3]] + ans[i][1]) % 360;
}
int cnt = 0;
for(int i = 0;i < SZ(ans);i++){
if(ans[i][0] == 1){
if(ans[i][1] != 0)cnt++;
}
else cnt++;
}
cout << cnt << endl;
for(int i = SZ(ans) - 1;i >= 0;i--){
if(ans[i][0] == 1 && ans[i][1] == 0)continue;
for(auto x : ans[i])cout << x << " ";
cout << endl;
}
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> T;
while(T--){
cin >> n >> m;
for(int i = 1;i <= n;i++)
for(int j = 1;j <= m;j++)
cin >> a[i][j];
bfs();
}
}
F题:
找规律的一个题,不难发现100及以上都是符合要求的数.那么分为三种情况,一种是小于10,一种是大于10小于100,一种是大于100.(官方的答案是分为两种情况,小于100的直接暴力求解,但是我是分成3种,因为可以预处理一下)
#include<iostream>
#include<cstring>
#include<string>
using namespace std;
#define ll long long
ll pre[20] = { 4,11,18,28,35,42,52,59,66,76 };
ll pre2[20] = { 0,0,1,1,1,2,2,2,3,4 };
ll fun(ll r) {
ll ans;
if (r <= 10) {
if (r == 0)return 0;
ans = pre2[r - 1];
}
else if (r < 100) {
ll a = r / 10;
ans = pre[a - 1];
for (ll i = a * 10 + 1; i <= r; i++) {
ll p1 = i / 10, p2 = i % 10;
if (p1 % 3 == 0 || p2 % 3 == 0 || i % 3 == 0) {
ans++;
}
}
}
else {
ans = 76 + r - 100;
}
return ans;
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
ll l, r;
ll T;
cin >> T;
while (T--) {
cin >> l >> r;
ll ans;
ans = fun(r) - fun(l - 1);
cout << ans << endl;
}
return 0;
}
J题(没搞明白但是下面的题解写的很好):
线段树
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define N 1000005
#define inf 0x3f3f3f3f
#define mod 1000000007
#define rep(i,s,t) for(ll i=s;i<=t;i++)
#define dep(i,s,t) for(ll i=t;i>=s;i--)
#define s(x) scanf("%lld",&x);
#define inf 0x3f3f3f3f
#define fi first
#define se second
#define ss(x,y) scanf("%lld%lld",&x,&y)
#define sss(x,y,z) scanf("%lld%lld%lld",&x,&y,&z)
#define pii pair<ll,ll>
#define piii pair<pii,ll>
#define lson now<<1
#define rson now<<1|1
struct node{
ll u,v;
ll lazy_d;
bool f;
node(ll u,ll v,ll lazy_d,bool f):u(u),v(v),lazy_d(lazy_d),f(f){};
node(){};
}t[N<<2];
struct node1{
ll u,v;
}temp[N];
ll d[N],cost[N];
void pushdown(ll now)
{
if(t[now].lazy_d)
{
t[lson].u+=t[now].lazy_d,t[lson].v+=t[now].lazy_d;
t[rson].u+=t[now].lazy_d,t[rson].v+=t[now].lazy_d;
t[lson].lazy_d+=t[now].lazy_d;
t[rson].lazy_d+=t[now].lazy_d;
t[now].lazy_d=0;
}
}
void pushup(ll now)
{
t[now].u=max(t[lson].u,t[rson].u);
t[now].v=min(t[lson].v,t[rson].v);
if(t[lson].u<=t[rson].v&&t[lson].f&&t[rson].f)t[now].f=true;
else t[now].f= false;
}
void build(ll l,ll r,ll now)
{
t[now].lazy_d=0;
if(l==r)
{
t[now].u=temp[l].u+d[l];
t[now].v=temp[l].v+d[l];
if(t[now].u<=t[now].v)t[now].f=true;
else t[now].f= false;
return;
}
ll mid=(l+r)>>1;
build(l,mid,lson),build(mid+1,r,rson);
pushup(now);
}
node check(ll l,ll r,ll now,ll L,ll R)
{
if(l>=L&&r<=R)
{
return t[now];
}
ll mid=(l+r)>>1;
pushdown(now);
if(mid<L)return check(mid+1,r,rson,L,R);
if(mid>=R)return check(l,mid,lson,L,R);
node x=check(l,mid,lson,L,R),y=check(mid+1,r,rson,L,R),ans=node(0,0,0,0);
ans.u=max(x.u,y.u),ans.v=min(x.v,y.v);
if(x.f&&y.f&&y.v>=x.u)ans.f=true;
else ans.f=false;
return ans;
}
void query1(ll l,ll r,ll now,ll L,ll R,ll w)
{
if(l>=L&&r<=R)
{
t[now].u+=w,t[now].v+=w;
t[now].lazy_d+=w;
return ;
}
ll mid=(l+r)>>1;
pushdown(now);
if(mid>=L)query1(l,mid,lson,L,R,w);
if(mid<R)query1(mid+1,r,rson,L,R,w);
pushup(now);
}
void query2(ll l,ll r,ll now,ll i,ll q,ll p)
{
if(l==i&&r==i)
{
t[now].u+=q;
t[now].v+=p;
if(t[now].u<=t[now].v)t[now].f=true;
else t[now].f= false;
return;
}
pushdown(now);
ll mid=(l+r)>>1;
if(mid>=i)query2(l,mid,lson,i,q,p);
if(mid<i)query2(mid+1,r,rson,i,q,p);
pushup(now);
}
void solve()
{
ll n,m,x,L,R,i,w,q,p;
s(n);
rep(i,1,n)s(temp[i].u);
rep(i,1,n)s(temp[i].v);
rep(i,1,n-1)s(cost[i]);
d[n]=0;
dep(i,1,n-1)d[i]=d[i+1]+cost[i];
build(1,n,1);
s(m);
while(m--)
{
s(x);
if(x==0)
{
ss(L,R);
node ans=check(1,n,1,L,R);
if(ans.f)printf("Yes\n");
else printf("No\n");
}
if(x==1)
{
ss(i,w);
query1(1,n,1,1,i,w-cost[i]);
cost[i]=w;
}
if(x==2)
{
sss(i,q,p);
query2(1,n,1,i,q-temp[i].u,p-temp[i].v);
temp[i].u=q;
temp[i].v=p;
}
}
}
int main()
{
ll T;
s(T);
while(T--)
{
solve();
}
}