10.5模拟赛

这么多模拟赛都没整理,能整理一天算一天吧qaq

T1题面

sol:应该不难吧,分别对横坐标和纵坐标取差的绝对值,易知:如果互质就可以看到,否则就不行。然后出题人很毒瘤要用unsigned long long。

#include <cstdio>
#include <algorithm>
using namespace std;
long long x1,y1,x2,y2,c1=0,c2=0;
unsigned long long x,y;
unsigned long long ABS(long long x,long long y)
{
    if(x<y)swap(x,y); if(y>0)return x-y; return (unsigned long long)(x)+(unsigned long long)(-y);
}
inline unsigned long long gcd(unsigned long long x,unsigned long long y){return (y==0)?x:gcd(y,x%y);}
int main()
{
    while(~scanf("%lld%lld%lld%lld",&x1,&y1,&x2,&y2))
    {
        x=ABS(x1,x2); y=ABS(y1,y2);
        if(x==0)if(y>1)puts("NO"),c2++;else puts("YE5"),c1++;
        else if(y==0)if(x>1)puts("NO"),c2++;else puts("YE5"),c1++;
        else if(gcd(x,y)==1)puts("YE5"),c1++;else puts("NO"),c2++;
    }if(c1>c2)puts("Poor xshen!");else if(c1==c2)puts("Friend Ship.");else puts("Yahoo!");
}

T2题面

sol:这就是大模拟啊,我代码在全班算很短了,我就简单说说模拟的方法,也没什么:我发现绝对值小于1e12,于是可以特判1e8一档,1e4一档,最后在一档,然后写一个过程负责输出一个四位数,不够就可以补零,然后拆成四位的样子逐个输出,再对应的输出单位如‘Y‘,‘W‘等。看代码吧out(补零的)和pout(不补零的)。

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
#define int long long
char re[100005],ss[100005],sss[100005],ssss[100005];
int n;
inline void out(int x)
{
  bool bo=0;
  if(x==0){putchar(‘0‘);return;}
  if(x%1000==0){printf("%lld",x/1000),putchar(‘Q‘);return;}
  if(x%100==0&&x<1000){printf("0%lld",x/100),putchar(‘B‘);return;}
  if(x%10==0&&x<100){printf("0%lld",x/10),putchar(‘S‘);return;}
  if(x<10){printf("0%lld",x);return;}
  if(x>=1000)printf("%lld",x/1000),putchar(‘Q‘),bo=0,x%=1000;else if(!bo&&x)putchar(‘0‘),bo=1;
  if(x>=100)printf("%lld",x/100),putchar(‘B‘),bo=0,x%=100;else if(!bo&&x)putchar(‘0‘),bo=1;
  if(x>=10)printf("%lld",x/10),putchar(‘S‘),bo=0,x%=10;else if(!bo&&x)putchar(‘0‘),bo=1;
  if(x>=1)printf("%lld",x/1),bo=0;else if(!bo&&x)putchar(‘0‘),bo=1;
}
inline void pout(int x)
{
  if(x==0){putchar(‘0‘);return;}
  if(x%1000==0){printf("%lld",x/1000),putchar(‘Q‘);return;}
  if(x%100==0&&x<1000){printf("%lld",x/100),putchar(‘B‘);return;}
  if(x%10==0&&x<100){printf("%lld",x/10),putchar(‘S‘);return;}
  if(x<10){printf("%lld",x);return;}
  bool bo=1;
  if(x>=1000)printf("%lld",x/1000),putchar(‘Q‘),bo=0,x%=1000;else if(!bo&&x)putchar(‘0‘),bo=1;
  if(x>=100)printf("%lld",x/100),putchar(‘B‘),bo=0,x%=100;else if(!bo&&x)putchar(‘0‘),bo=1;
  if(x>=10)printf("%lld",x/10),putchar(‘S‘),bo=0,x%=10;else if(!bo&&x)putchar(‘0‘),bo=1;
  if(x>=1)printf("%lld",x/1),bo=0;else if(!bo&&x)putchar(‘0‘),bo=1;
}
inline void write(char *s,int opt)
{
  int i,j,num=0LL,boo; n=strlen(s+1);
  int pp=0,bo; i=1; bool ooo=0;
  while(s[i]==‘+‘||s[i]==‘-‘)
  {
    pp+=(s[i]==‘-‘); i++;
  }bo=0; bool arr=0; int oo=0;
  if(pp&1&&!opt)for(j=1;j<=n;j++)if(isdigit(s[j])){putchar(‘F‘);break;}for(;i<=n;i++) if(s[i]!=‘.‘)num=num*10LL+(s[i]-‘0‘);else break;
  if(num>0)
  {
    if(num>=100000000)
    {
      pout(num/100000000); putchar(‘Y‘); num%=100000000; if(num)out(num/10000); if(num/10000)putchar(‘W‘); num%=10000; if(num)out(num);
    }
    else if(num>=10000)
    {
      pout(num/10000); putchar(‘W‘); num%=10000; if(num)out(num);
    }else pout(num);
  }else putchar(‘0‘);
  if(s[i]==‘.‘)
  {
    boo=0; int las=0;
    for(j=i+1;j<=n;j++){if(s[j]!=‘0‘){boo=1; break;}}
    if(boo)
    {
      putchar(‘D‘); las=n; for(las=n;las>=i+1;las--)if(s[las]!=‘0‘)break; for(j=i+1;j<=las;j++)putchar(s[j]);
    }else return;
  }else return;
}
inline int check(char *s){int i=1,pp=0; while(s[i]==‘+‘||s[i]==‘-‘){pp+=(s[i]==‘-‘);i++;} return (pp&1)?-1:1;}
signed main()
{
  scanf("%s",re+1); int i,j,num=0LL,flg=0,boo=0; n=strlen(re+1);
  for(i=1;i<=n;i++)if(isdigit(re[i])&&re[i]!=‘0‘){boo=1;break;} if(!boo)return putchar(‘0‘),0;
  for(i=1;i<=n;i++){if(re[i]==‘/‘){flg=1;break;}}
  if(flg)
  {
    int cnt=0,num=0,oo=0; for(i=1;i<=n;i++){if(re[i]!=‘/‘)ss[++cnt]=re[i];else break; if(isdigit(re[i]))oo=oo*10+(re[i]-‘0‘);} if(!oo)return putchar(‘0‘),0;
    cnt=0; n=strlen(re+1); for(j=i+1;j<=n;j++){sss[++cnt]=re[j];if(isdigit(re[j]))num=num*10+re[j]-‘0‘;}
    if((check(ss)<0||check(sss)<0)&&(check(ss)>0||check(sss)>0))putchar(‘F‘); if(num!=1) {write(sss,1); putchar(‘f‘);putchar(‘z‘);} write(ss,1);
  }else write(re,0);
}

T3题面

sol:可以对每个k开一颗动态开点线段树,存入每个颜色的方案数,把每个点的方案数弄个前缀和一样的东西存起来,然后当前点的方案数就是左上角矩阵的前缀和减去当前点的方案数,见代码。

#include <cstdio>
#include <cstring>
using namespace std;
const int N=1005,md=1000000007;
int n,m,k,a[N][N],f[N][N],s[N][N],rt[N*N],cnt=0;
struct segtree{int sum,ls,rs;}Tree[N*N*8];
inline void ins(int &x,int l,int r,int po,int v)
{
    if(x==0)x=++cnt; (Tree[x].sum+=v)%=md; if(l==r)return;
    int mid=(l+r)>>1; if(po<=mid)ins(Tree[x].ls,l,mid,po,v); else ins(Tree[x].rs,mid+1,r,po,v);
}
inline int que(int l,int r,int ql,int qr,int x)
{
    if(x==0||ql>qr)return 0; if(l==ql&&r==qr)return Tree[x].sum%md; int mid=(l+r)>>1,re=0;
    if(qr<=mid)return que(l,mid,ql,qr,Tree[x].ls)%md; else if(ql>mid)return que(mid+1,r,ql,qr,Tree[x].rs)%md;
    else return (que(l,mid,ql,mid,Tree[x].ls)%md+que(mid+1,r,mid+1,qr,Tree[x].rs)%md)%md;
}
signed main()
{
    int i,j; scanf("%d%d%d",&n,&m,&k); memset(f,0,sizeof f); memset(rt,0,sizeof rt);
    for(i=1;i<=n;i++)for(j=1;j<=m;j++)scanf("%d",&a[i][j]);
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=m;j++)
        {
            if(i==1&&j==1){f[i][j]=s[i][j]=1;continue;}
            (f[i][j]+=(s[i-1][j-1]-que(1,m,1,j-1,rt[a[i][j]])%md+md)%md)%=md;
            s[i][j]=(((s[i-1][j]+s[i][j-1])%md-s[i-1][j-1]+f[i][j])%md+md)%md;
        }for(j=1;j<=m;j++) ins(rt[a[i][j]],1,m,j,f[i][j]%md);
    }printf("%d\n",f[n][m]%md);
}

原文地址:https://www.cnblogs.com/gaojunonly1/p/9745589.html

时间: 2024-10-18 21:38:11

10.5模拟赛的相关文章

10.2模拟赛总结

10.2 模拟赛总结 T1. 数位dp: 一个非常非常非常非常显然的数位 DP \([L,R] = [1,R]-[1,L-1]\) 所以是分别求两次小于等于某个数字的方案数 \(f(i,j,k)\) 表示从低位数起的第 \(i\) 位,按照规则计算后答案为 \(j\quad (j=0,1)\) \(k\) 表示只考虑后面结尾和 \(lmt\)后面几位 的大小关系 \((k=0,1)\) 考虑第 \(i+1\) 位,算一下新构成的数字并判断下大小就可以了 注意到 \(L,R\) 数据范围特别大,需

10.22 模拟赛

10.22 模拟赛 T1 染色 考虑每个连通块删成一棵树就好了. mmp场上就我路径压缩写炸.... #include<iostream> #define MAXN 200006 using namespace std; int n , m; int fa[MAXN] , siz[MAXN] , book[MAXN] , sz[MAXN]; int find(int x) { return x == fa[x] ? x : fa[x] = find(fa[x]); } int main() {

10.31 模拟赛

10.31 模拟赛 A LIS 考虑每个数字前从 $ m $ 降序构造到 $ a_i $ 即可. #include <iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<vector> using namespace std; #define MAXN 300006 int n , m , k; int A[MAXN]; vector<int&g

10 01模拟赛订正

好吧,这是我第一次写模拟赛的订正,主要是有时间而且这次的题确实好... 第一题确实好,用的算法人人都会,就是看你能不能想到,我考只打了O(n^4)的暴力,最后还苦逼的MLE,爆零了... 暴力就不多说了...枚举两个点更新其他的点... 其实我考场上思考的是,能被标记的点都与其他的点有什么联系,可惜,除了模拟题目的做法,就不会了... 那让我们就认真地思考一发:我们设A(x1,x2),B(x2,c2),C(x3,c3)来更新D点,只有:有两个点横坐标相等,有两个点纵坐标相等,才可以更新出来一个新

2019.10.24模拟赛赛后总结

本文原创,如果有不到位的地方欢迎通过右下角的按钮私信我! A.Icow Player 题目描述 被无止境的农活压榨得筋疲力尽后,Farmer John打算用他在MP3播放器市场新买的iCow来听些音乐,放松一下.FJ的iCow里存了N(1 <= N <= 1,000)首曲子,按1..N依次编号.至于曲子播放的顺序,则是按一个Farmer John自己设计的算法来决定: * 第i首曲子有一个初始权值R_i(1 <= R_i <= 10,000). * 当一首曲子播放完毕,接下来播放的

10.1 模拟赛

由于算错了inf 又ak失败了 过于菜 T1 年轮蛋糕 loj 2758 题目大意: n个数构成的环 把这个环分成三段 使最小的最大 求这个最小段的和的最大值 思路: 可以想到二分 因为log方可以过 所以可以二分长度后lower_bound找断点 或者使用滑动窗口 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cma

10.27 模拟赛

这一次终极被吊打 甚至没进前十 T2 最后改错 T3 没写正解 T1 elim 题目大意: n 行 m 列的游戏棋盘,一行或一列上有连续 三个或更多的相同颜色的棋子时,这些棋子都被消除 当有多处可以被消除时,这些地方的棋子将同时被消除 求消除后的棋盘 思路: sb模拟 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cm

10.4 模拟赛

写在前面: 我发现我每一次写题解都是改题改不出来了QAQ 其实今天的题都还好啦. T1 可见点数 其实就是 luogu仪仗队 的数据扩大版,开个long long然后数组开大点就可以过了. T2 射击 这个题就很有意思了. 小W和他的东厂厂长叔叔去打窗户.... 其中两句话很有误导的含义,不少人都死在了这句话上面.[其实只有我 /滑稽 每秒只能彻底打破一扇窗户. 你不能要求他们叔侄两个打破不同的窗户获得的快乐值必须相同. 错误的贪心策略: 把所有的窗户按时间排序,时间相同按价值排序,然后模拟选择

17.2.10 NOIP模拟赛 藏妹子之处(excel)

藏妹子之处(excel) 问题描述: 今天CZY又找到了三个妹子,有着收藏爱好的他想要找三个地方将妹子们藏起来,将一片空地抽象成一个R行C列的表格,CZY要选出3个单元格.但要满足如下的两个条件: (1)任意两个单元格都不在同一行. (2)任意两个单元格都不在同一列. 选取格子存在一个花费,而这个花费是三个格子两两之间曼哈顿距离的和(如(x1,y1)和(x,y2)的曼哈顿距离为|x1-x2|+|y1-y2|).狗狗想知道的是,花费在minT到maxT之间的方案数有多少. 答案模100000000