7.22 NOIP模拟7
又是炸掉的一次考试
T1.方程的解
本次考试最容易骗分的一道题,但是由于T2花的时间太多,我竟然连a+b=c都没判。。暴力掉了40分。
首先a+b=c,只有一组解。
然后是a=1,b=1,答案是c-1,不解释。
对于最大的数据,我们可以用exgcd求出一组特解,之后的通解为x+(b/gcd)*k, y+(a/gcd)*k.
求出正整数解的个数即可。
注意有很多特判,慢慢调试就好(改这题的时间比我改T3的时间都长)
#include<bits/stdc++.h>
#define m 65535
#define int long long
using namespace std;
int t,a,b,c,x,y;
long long ans;
int exgcd(int a,int b,int &x,int &y)
{
if(b==)
{
x=,y=;
return a;
}
int gcd=exgcd(b,a%b,y,x);
y-=(a/b)*x;
return gcd;
}
main()
{
scanf("%lld",&t);
while(t--)
{
ans=;
scanf("%lld%lld%lld",&a,&b,&c);
if(a+b==c&&a>=&&b>=)
{
puts("");
continue;
}
if(a<&&b<&&c<)
a=-a,b=-b,c=-c;
if(a==&&b==)
{
ans=c-;
if(ans>&&ans<=)
{
printf("%lld\n",ans);
continue;
}
if(ans<=)
puts("");
if(ans>m)
puts("ZenMeZheMeDuo");
continue;
}
if(t<=&&a<=&&a>=&&b<=&&b>=&&c>=&&c<=)
{
for(int i=;i<=;i++)
for(int j=;j<=;j++)
{
if(a*i+b*j>c)break;
if(a*i+b*j==c)ans++;
}
if(ans>m)puts("ZenMeZheMeDuo");
else printf("%lld\n",ans);
continue;
}
if(a==&&b==)
{
if(c==)puts("ZenMeZheMeDuo");
else puts("");
continue;
}
if(a==)
{
if(b>)
{
if(c>&&(!(c%b)))puts("ZenMeZheMeDuo");
else puts("");
}
if(b<)
{
if(c<&&(!(c%b)))puts("ZenMeZheMeDuo");
else puts("");
}
continue;
}
if(b==)
{
if(a>)
{
if(c>&&(!(c%a)))puts("ZenMeZheMeDuo");
else puts("");
}
if(a<)
{
if(c<&&(!(c%a)))puts("ZenMeZheMeDuo");
else puts("");
}
continue;
}
if((a<&&b<&&c>=)||(a>&&b>&&c<=))
{
puts("");
continue;
}
if(a<&&b<&&c<)
a=-a,b=-b,c=-c;
int gcd=exgcd(a,b,x,y);
if(c%gcd)
{
puts("");
continue;
}
if(a*b<)
{
puts("ZenMeZheMeDuo");
continue;
}
int k=c/gcd,xx=b/gcd,yy=a/gcd;
x*=k,y*=k;
if(xx<)
xx=-xx,yy=-yy;
if(x<=)
{
int xxx=x/xx+;
x+=xxx*xx,y-=yy*xxx;
}
if(y<=)
{
int xxx=y/yy+;
x-=xx*xxx,y+=yy*xxx;
}
while(x<=)
x+=xx,y-=yy;
while(y<=)
x-=xx,y+=yy;
if(!x||!y)
{
puts("");
continue;
}
if(x/y<||y/x<)
{
puts("");
continue;
}
int aa=x/xx+,bb=y/yy+;
if(!(x%xx))aa--;
if(!(y%yy))bb--;
ans=max(aa,bb);
if(ans>m)puts("ZenMeZheMeDuo");
else printf("%lld\n",ans);
}
return ;
}
T2.visit
本场考试最可惜的一道题,打出正解,却因为答案为0的特判wa(改一个字符,70分->AC)
考试的时候先打了个n^3dp,然后开始找规律
10,5,5 = C(10,5)*C(10,0);
10,4,4 = C(10,5)*C(10,1); 10,4,6=C(10,4)*C(10,0);
10,3,3 = C(10,5)*C(10,2); 10,3,5=C(10,4)*C(10,1); 10,3,7=C(10,3)*C(10,0);
10,2,2 = C(10,5)*C(10,3); 10,2,4=C(10,4)*C(10,2); 10,2,6=C(10,3)*C(10,1); 10,2,8=C(10,2)*C(10,0);
10,1,1 = C(10,5)*C(10,4);
10,0,0 = C(10,5)*C(10,5);
这个表我没有打完,但是我感觉已经很显然了,ans=C(t,(t-n-m)/2)*C(t,(t-n+m)/2);(n>m)
注意特判无解情况,t-n-m为奇数时,必然无解。
然后我终于理解了数据范围最后,mod为若干质数乘积的意思。。。
恩,然后我就开始手推crt,码码码,大概一个小时调完了,和dp对了几个点,感觉没啥问题,没打对拍放心的去看T3了。
考后发现自己打了个这个:
if(((t%(n+m))&))
{
puts("");
return ;
}
???????????我干了啥?把%改成-,AC。一个特判卡掉30分,我。。。。
至于组合数的解释,请参考其他人的题解。(其实是我不会解释)
#include<cstdio>
#include<cmath>
using namespace std;
inline int read(){
register int ss=;register char bb=getchar();
while(bb<||bb>)bb=getchar();
while(bb>=&&bb<=)ss=(ss<<)+(ss<<)+(bb^),bb=getchar();
return ss;
}
inline long long power(long long x,int y,int const mod){
long long ans=;
for(;y;y>>=,x=(x<<)%mod)
if(y&)ans=(ans+x)%mod;
return ans;
}
int const t=read(),p=read();
int n,m,tot;
long long prime[],f[],invv[];
inline void split(long long x,int lit){
for(register int i=;i<=lit && x^;++i)
if(!(x%i))prime[++tot]=i,x/=i;
if(x^)prime[++tot]=x;
return ;
}
long long exgcd(long long a,long long b,long long &x,long long &y){
if(!b)return x=,y=,;
long long z=exgcd(b,a%b,x,y),lh=x;
x=y,y=lh-a/b*y;
return z;
}
inline long long inv(long long x,long long mod){
long long a,b,c=exgcd(x,mod,a,b);
if(c^)return -;
if(a<)a=a%mod+mod;
return a;
}
inline long long cp(long long x,long long y,long long const mod){
if(x<y)return ;
if(!y || x==y)return ;
if(y>x-y)y=x-y;
long long a=,b=;
for(register int i=;i<y;++i)
a=a*(x-i)%mod,b=b*(y-i)%mod;
return a*inv(b,mod)%mod;
}
long long lucas(long long x,long long y,long long mod){
if(x<y)return ;
if(x==y)return ;
return y?cp(x%mod,y%mod,mod)*lucas(x/mod,y/mod,mod)%mod:;
}
inline long long china(){
long long ans=;
for(register int i=;i<=tot;++i)
ans=(ans+power(p/prime[i],power(invv[i],f[i],p),p))%p;
return ans;
}
inline long long cq(int x,int y){
for(register int i=;i<=tot;++i)
f[i]=lucas(x,y,prime[i]);
return china();
}
inline void swap(int &x,int &y){
int z=x;
x=y,y=z;
return ;
}
signed main(){
n=read(),m=read();
if(n<m)swap(n,m);
split(p,sqrt(p));
for(register int i=;i<=tot;++i)
invv[i]=inv(p/prime[i],prime[i]);
printf("%lld",cq(t,t-n+m>>)*cq(t,t-n-m>>)%p);
return ;
}
这是remarkable的代码
T3.光
没想到一道模拟题卡掉了我50分。。。暴力都打错了,骗到20分,考完后发现加clock等一大堆特判可以卡到80分。
正解就是模拟,但是优化了一下。首先,在原来的基础上,可以直接考虑到当前状态的终点:二分。
在同一种状态中,横纵坐标之和或差必然不变,因此我们可以将黑块存进保存坐标之和或差的vector中,给每个vector排序后二分。
但是我们似乎忽略了一个问题:如何统计答案?
一个非常简单却不好想的结论:若一个块被经过,则光线必然只穿过他的一条对角线。
证明如下:
我们给每两个相邻的方块染上不同的颜色,则同一种状态的光线只经过同种颜色的方块。而除了反向反射的两种状态,另外两种反射方式必然从一种颜色的方块变成另一种,即,经过右下->左上对角线和右上->左下对角线的光线穿过的方块颜色必不相同,所以同一方块不可能被穿过两条对角线。
既然如此,那么就又有一个非常显然的结论:一个方块最多被经过两次,两次穿过同一对角线且方向相反。
那么一个方块被经过两次的条件呢?当且仅当发生了反向的反射。同样,若发生了反向的反射,反向光线会将原光线的所有路径重走一遍,因此,一旦发生反向反射,所有被经历的方块都会被穿过两次。否则,每个方块仅被穿过一次。
因此,我们可以记录是否发生了反向的反射,若发生了,最后统计的答案数/2。计算每种状态的贡献时,只需将起始节点和终点的横(纵)坐标相减即可。
注意反射情况十分复杂,分类讨论即可。为了方便,多调几个STL挺好的。
#include<bits/stdc++.h>
#define mk(a,b,c) mp(a,mp(b,c))
#define mp(a,b) make_pair(a,b)
#define pb push_back
using namespace std;
int n,m,k;
long long ans=;
bool v;
vector<int>h[],g[];
map<pair<int,pair<int,int> >,bool>c;
map<pair<int,int>,bool>kk;
int main()
{
scanf("%d%d%d",&n,&m,&k);int kkk=max(n,m);
for(int i=;i<=k;i++)
{
int x,y;
scanf("%d%d",&x,&y);
kk[mp(x,y)]=true;
h[x+y].pb(x-y);
g[x-y+kkk].pb(x+y);
}
for(int i=,x,y;i<=m+;i++)
{
x=,y=i;
kk[mp(x,y)]=true;
h[x+y].pb(x-y);
g[x-y+kkk].pb(x+y);
x=n+;
kk[mp(x,y)]=true;
h[x+y].pb(x-y);
g[x-y+kkk].pb(x+y);
}
for(int i=,x,y;i<=n+;i++)
{
x=i,y=;
kk[mp(x,y)]=true;
h[x+y].pb(x-y);
g[x-y+kkk].pb(x+y);
y=m+;
kk[mp(x,y)]=true;
h[x+y].pb(x-y);
g[x-y+kkk].pb(x+y);
}
for(int i=;i<=kkk+kkk+;i++)
sort(h[i].begin(),h[i].end()),
sort(g[i].begin(),g[i].end());
int x,y,zt,i=;
string ss;
cin>>x>>y>>ss;
if(ss=="NE")zt=;
if(ss=="NW")zt=;
if(ss=="SE")zt=;
if(ss=="SW")zt=;
while(!c[mk(x,y,zt)])
{
c[mk(x,y,zt)]=true;i++;
if(zt==)
{
int cc=*--upper_bound(h[x+y].begin(),h[x+y].end(),x-y),
xx=(x+y+cc)>>,yy=(x+y-cc)>>;
if(i^)ans+=abs(x-xx);
if((kk[mp(xx+,yy)]&&kk[mp(xx,yy-)])
||(!kk[mp(xx+,yy)]&&!kk[mp(xx,yy-)]))
{
zt=,x=xx+,y=yy-;
if(i^)v=true;
}
else if(kk[mp(xx+,yy)])
zt=,x=xx,y=yy-;
else if(kk[mp(xx,yy-)])
zt=,x=xx+,y=yy;
}
else if(zt==)
{
int cc=*upper_bound(h[x+y].begin(),h[x+y].end(),x-y),
xx=(x+y+cc)>>,yy=(x+y-cc)>>;
if(i^)ans+=abs(x-xx);
if((kk[mp(xx-,yy)]&&kk[mp(xx,yy+)])
||(!kk[mp(xx-,yy)]&&!kk[mp(xx,yy+)]))
{
zt=,x=xx-,y=yy+;
if(i^)v=true;
}
else if(kk[mp(xx-,yy)])
zt=,x=xx,y=yy+;
else if(kk[mp(xx,yy+)])
zt=,x=xx-,y=yy;
}
else if(zt==)
{
int cc=*--upper_bound(g[x-y+kkk].begin(),g[x-y+kkk].end(),x+y),
xx=(x-y+cc)>>,yy=(cc-x+y)>>;
if(i^)ans+=abs(x-xx);
if((kk[mp(xx+,yy)]&&kk[mp(xx,yy+)])
||(!kk[mp(xx+,yy)]&&!kk[mp(xx,yy+)]))
{
zt=,x=xx+,y=yy+;
if(i^)v=true;
}
else if(kk[mp(xx+,yy)])
zt=,x=xx,y=yy+;
else if(kk[mp(xx,yy+)])
zt=,x=xx+,y=yy;
}
else if(zt==)
{
int cc=*upper_bound(g[x-y+kkk].begin(),g[x-y+kkk].end(),x+y),
xx=(x-y+cc)>>,yy=(cc-x+y)>>;
if(i^)ans+=abs(x-xx);
if((kk[mp(xx-,yy)]&&kk[mp(xx,yy-)])
||(!kk[mp(xx-,yy)]&&!kk[mp(xx,yy-)]))
{
zt=,x=xx-,y=yy-;
if(i^)v=true;
}
else if(kk[mp(xx+,yy)])
zt=,x=xx,y=yy-;
else if(kk[mp(xx,yy+)])
zt=,x=xx-,y=yy;
}
}
printf("%lld\n",v?ans/:ans);
return ;
}
大模拟
7.22 NOIP模拟7的更多相关文章
- 8.22 NOIP 模拟题
8.22 NOIP 模拟题 编译命令 g++ -o * *.cpp gcc -o * *.c fpc *.pas 编译器版本 g++/gcc fpc 评测环境 位 Linux, .3GHZ CPU ...
- 2018.9.22 NOIP模拟赛
*注意:这套题目应版权方要求,不得公示题面. 从这里开始 Problem A 妹子 Problem B 旅程 Problem C 老大 因为业务水平下滑太严重,去和高一考NOIP模拟,sad... P ...
- 9.22 NOIP模拟题
吉林省信息学奥赛 2017 冬令营 ...
- 2018.08.22 NOIP模拟 string(模拟)
string [描述] 给定两个字符串 s,t,其中 s 只包含小写字母以及*,t 只包含小写字母. 你可以进行任意多次操作,每次选择 s 中的一个*,将它修改为任意多个(可以是 0 个)它的前一个字 ...
- 2021.5.22 noip模拟1
这场考试考得很烂 连暴力都没打好 只拿了25分,,,,,,,,好好总结 T1序列 A. 序列 题目描述 HZ每周一都要举行升旗仪式,国旗班会站成一整列整齐的向前行进. 郭神作为摄像师想要选取其中一段照 ...
- 9.22 noip模拟试题
水灾(sliker.cpp/c/pas) 1000MS 64MB 大雨应经下了几天雨,却还是没有停的样子.土豪CCY刚从外地赚完1e元回来,知道不久除了自己别墅,其他的地方都将会被洪水淹没. CCY ...
- 2018.08.22 NOIP模拟 shop(lower_bound+前缀和预处理)
Shop 有 n 种物品,第 i 种物品的价格为 vi,每天最多购买 xi 个. 有 m 天,第 i 天你有 wi 的钱,你会不停购买能买得起的最贵的物品.你需要求出你每天会购买多少个物品. [输入格 ...
- 2018.08.22 NOIP模拟 or(线段树)
or [描述] 构造一个长度为 n 的非负整数序列 x,满足 m 个条件,第 i 个条件为x[li] | x[li+1] | - | x[ri]=pi. [输入] 第一行两个整数 n,m.接下来 m ...
- 18.9.22 noip模拟赛
此题为找规律.期望100 实际100 #include<cstdio> #include<cstring> #include<iostream> #include& ...
随机推荐
- PHP 通过 ReflectionMethod 反射类方法获取注释返回 false 的问题解决
php 通过反射 ReflectionMethod 类来获取类方法的相关信息,其中就包含方法的注释内容. 问题描述 在公司测试环境运行以下代码,如果是 cli 命令行模式运行,正常输出代码注释.如果是 ...
- win10安装python
下载地址:https://www.python.org/downloads/release/python-365/ 安装完成后,在cmd里输入 python ,检查是否安装成功
- 个性化推荐产品功能的设计和B端产品的功能策划方式
宜信科技中心财富管理产品部负责人Bob,与大家一起聊聊个性化推荐产品功能的设计和B端产品的功能策划方式. 拓展阅读:回归架构本质,重新理解微服务|专访宜信开发平台(SIA)负责人梁鑫 智慧金融时代,大 ...
- 新手学分布式-动态修改Nginx配置的一些想法
本人是分布式的新手,在实际工作中遇到了需要动态修改nginx的需求,因此写下实现过程中的想法.Nginx功能强大且灵活,所以这些权当抛砖引玉,希望可以得到大家的讨论和指点.(具体代码在 https:/ ...
- IMongoQuery的使用-C#
一.Mongodb的IMongoQuery的使用 引用命名空间:MongoDB.Driver;MongoDB.Driver.Builders; Query.All("name", ...
- 采用WPF开发截图程序,so easy!
前言 QQ.微信截图功能已很强大了,似乎没必要在开发一个截图程序了.但是有时QQ热键就是被占用,不能快速的开启截屏:有时,天天挂着QQ,领导也不乐意.既然是程序员,就要自己开发截屏工具,功能随心所欲 ...
- PhpSpreadsheet 导出特定格式 — 广告请款单
需求说明 最近需要实现一个导出这种格式的Excel表单,之前都有用过导出Excel的功能,但大都是表头+数据的形式,只用于获取数据,没有太多样式要求,不用合并单元格.合并居中等,也不用对每一行数据特异 ...
- 通过反射对任意class类中方法赋值的方式
import org.apache.commons.lang3.StringUtils;import org.slf4j.Logger;import org.slf4j.LoggerFactory;i ...
- thinkphp5底层基类封装、内部类函数
记录下thinkphp5自定义底层基类.内部类函数使用笔记 大部分笔记来自tp手册. 底层常用代码的封装 在控制器中基类的起着至关重要的作用,整个项目的代码安全,复杂程度,易读性都要看你项目的基类架构 ...
- 物理机安装Kali Linux + Windows10双系统安装教程
转自 https://www.linuxidc.com/Linux/2018-08/153429.htm 一.镜像下载: 根据需求下载自己需要的版本 从官网下载kali 2018.2 的安装包:htt ...