noip32
T1
暴力很好打,然而我是最后打的,所以只有40pts,其他人都有80pts的说
其实也应该想到的吧
80pts用的 \(set\) ,有个log,所以A不了。
正解:
把 \(set\) 换成 \(queue\) ,开 \(b\) 个 队列,队首依次塞进对应的素数,每次操作取出队首元素最小的队列,用该队列的队首元素去更新它本身及其之后的队列,在队尾加入乘上该队列所对应的素数即可。
注意,第一次队列里没塞1,直接塞素数,相当于进行了一次操作,所以当操作到第 \(k-1\) 次时,直接输出当前拿出的队列的队首元素即可。
\(queue\) 每次操作都是 \(O(1)\) 的,所以总复杂度 \(O(BK)\) ,可过。
Code
#include<queue>
#include<cstdio>
#define re register
#define int64_t long long
using std::queue;
namespace OMA
{
int k,b;
queue<int64_t>q[16];
int f[16]={0,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47};
signed main()
{
scanf("%d%d",&b,&k);
for(re int i=1; i<=b; i++)
{ q[i].push(f[i]); }
for(re int i=1,id=1; i<=k-1; i++,id=1)
{
for(re int j=2; j<=b; j++)
{ if(q[j].front()<=q[id].front()){ id = j; } }
for(re int j=id; j<=b; j++)
{ q[j].push(1LL*f[j]*q[id].front()); }
if(i==k-1)
{ printf("%lld\n",q[id].front()); return 0 ; }
q[id].pop();
}
return 0;
}
}
signed main()
{ return OMA::main(); }
T2
记搜。
Code
#include<map>
#include<cstdio>
#define a first
#define b second
#define re register
#define int long long
using std::map;
using std::pair;
using std::make_pair;
const int MAX = 1<<6;
typedef pair<int,int>my;
namespace OMA
{
my d[7];
int n,cnt,top;
map<my,int>dp;
int id[MAX],sum[MAX];
const int p = 1e9+7;
inline int dfs(int tmp,my res)
{
if(dp[res])
{ return dp[res]; }
dp[res] = 1;
for(re int i=1; i<=top; i++)
{
int tot = 0,flag = 0;
for(re int j=1; j<=top; j++)
{
if(!(i&j))
{ continue ; }
if((res.a>>j)&1)
{ tot++; }
if((res.b>>j)&1)
{ flag = 1; }
if(flag||tot>1)
{ break ; }
}
if(flag||tot>1)
{ continue ; }
if((res.a>>i)&1)
{ (dp[res] += sum[i]%p*dfs(tmp+1,make_pair(res.a^(1LL<<i),res.b|(1LL<<i)))%p) %= p; }
else
{ (dp[res] += sum[i]%p*dfs(tmp+1,make_pair(res.a|(1LL<<i),res.b))%p) %= p; }
}
return dp[res];
}
signed main()
{
scanf("%lld",&n);
for(re int i=2; i*i<=n; i++)
{
if(n%i==0)
{
d[++cnt].a = i;
while(n%i==0)
{ d[cnt].b++,n /= i; }
}
}
if(n!=1)
{ d[++cnt] = make_pair(n,1); }
for(re int i=1; i<=cnt; i++)
{ id[1<<i-1] = i; /*printf("%lld %lld\n",d[i].a,d[i].b);*/ }
top = (1<<cnt)-1,sum[0] = 1;
for(re int i=1; i<=top; i++)
{ sum[i] = sum[i^(i&-i)]*d[id[i&-i]].b; /*printf("%lld ",sum[i]);*/ }
//printf("\n");
printf("%lld\n",dfs(0,make_pair(0,0))-1);
return 0;
}
}
signed main()
{ return OMA::main(); }
T3
看起来比较可做的一道,高斯消元很好想到,方程求解,代入检验。
然而我题读错+不会求 \(\theta\) ,就只拿了30pts。
正解:
按照题目所说的坐标转换,随机找组坐标列两个方程,发现一共有四个未知量,分别为 \(\cos{\theta}\times scale ,\sin{\theta}\times scale,d_{x},d_{y}\) ,所以就再随机找一组坐标来求解,每次求解完,带回检验是否符合要求。
发现,求解出来的是 \(\cos{theta}\times scale,\sin(\theta)\times scale\) ,所以如何求 \(scale\) 和 \(\theta\) ?
\(scale\) ,根据三角函数相关知识 \(\sin^{2}{\theta}+\cos^{2}{\theta}=1\) 可求得 \(scale\) ,给那俩玩意平方相加开根号即可。
\(\theta\),camth库自带函数 \(acos\) ,记得根据 \(\sin\) 值调整正负。
每回随机找两组,因为要求一半以上,所以找对的概率为 \(\frac{1}{4}\),找错的概率为 \(\frac{3}{4}\),找50组,\(\frac{3}{4}^{50}<10^{-5}\),所以可过。
复杂度 \(O(n)\) ,附带比较大的常数(上界大概为50)。
剩下的就是调试的问题,很exsb,给方程赋值的时候一定不要搞错了,注意统计合法非法时的判断条件,不要混用。
scale记得开根号
附带一系列精美调试信息
Code
#include<ctime>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#define MAX 100010
#define re register
namespace OMA
{
int n,m=4;
double ar[5][6],tmp[5];
double x1[MAX],y1[MAX],x2[MAX],y2[MAX];
const double eps = 1e-6;
inline double abs(double a)
{ return a>=0.0?a:-a; }
inline void swap(double &a,double &b)
{ double t=a; a=b; b=t; }
inline void Gauss()
{
for(re int i=1; i<=m; i++)
{
int k = i;
for(re int j=i+1; j<=m; j++)
{
//if(abs(ar[j][j])>eps&&j<i)
//{ continue ; }
if(abs(ar[j][i])>abs(ar[k][i]))
{ k = j; }
}
for(re int j=1; j<=m+1; j++)
{ swap(ar[i][j],ar[k][j]); }
//if(abs(ar[i][i])<=eps)
//{ continue ; }
for(re int j=1; j<=m; j++)
{
if(i!=j)
{
double temp = ar[j][i]/ar[i][i];
for(k = i+1; k<=m+1; k++)
{ ar[j][k] -= temp*ar[i][k]; }
}
}
}
for(re int i=1; i<=m; i++)
{ tmp[i] = ar[i][m+1]/ar[i][i]; }
}
struct stream
{
template<typename type>inline stream &operator >>(type &s)
{
int w=1,k=0,a=0,b=0; s=0; char ch=getchar();
while(ch<'0'||ch>'9'){ if(ch=='-')w=-1; ch=getchar(); }
while((ch>='0'&&ch<='9')||ch=='.')
{
if(ch=='.'){ b = 1; }
else if(!b)
{ s = s*10+ch-'0'; }
else
{ k = k*10+ch-'0',a++; }
ch = getchar();
}
return s=(pow(0.1,a)*k+s)*w,*this;
}
}cin;
signed main()
{
srand(time(NULL));
cin >> n;
for(re int i=1; i<=n; i++)
{ cin >> x1[i] >> y1[i] >> x2[i] >> y2[i]; }
int cnt = 0;
while(cnt<=50)
{
int p1 = rand()%n+1,p2 = rand()%n+1;
if(p1==p2)
{ continue ; }
cnt++;
ar[1][1] = x1[p1],ar[1][2] = -y1[p1],ar[1][3] = 1,ar[1][4] = 0,ar[1][5] = x2[p1];
ar[2][1] = y1[p1],ar[2][2] = x1[p1],ar[2][3] = 0,ar[2][4] = 1,ar[2][5] = y2[p1];
ar[3][1] = x1[p2],ar[3][2] = -y1[p2],ar[3][3] = 1,ar[3][4] = 0,ar[3][5] = x2[p2];
ar[4][1] = y1[p2],ar[4][2] = x1[p2],ar[4][3] = 0,ar[4][4] = 1,ar[4][5] = y2[p2];
Gauss();
int many = 0;
for(re int i=1; i<=n; i++)
{
if(abs(x1[i]*tmp[1]-y1[i]*tmp[2]+tmp[3]-x2[i])<=eps&&abs(y1[i]*tmp[1]+x1[i]*tmp[2]+tmp[4]-y2[i])<=eps)
{ many++; }
}
//printf("many=%d\n",many);
if(many>n/2)
{
//printf("QAQ\n");
double scale = sqrt(tmp[1]*tmp[1]+tmp[2]*tmp[2]);
/*for(re int i=1; i<=m; i++)
{
for(re int j=1; j<=m+1; j++)
{ printf("%0.6lf ",ar[i][j]); }
printf("\n");
}*/
//printf("cos=%0.10lf sin=%0.10lf\n",tmp[1]/scale,tmp[2]/scale);
printf("%0.10lf\n%0.10lf\n%0.10lf %0.10lf\n",(tmp[2]/scale>=0.0?1.0:-1.0)*acos(tmp[1]/scale),scale,tmp[3],tmp[4]);
return 0;
}
}
return 0;
}
}
signed main()
{ return OMA::main(); }
反思总结:
- 打暴力不要占用太多时间,但一定要都打上,能优化的地方尽量去优化。
- 注意开题顺序,不要死磕一道题。
- 注意细节,读题不要出错。真不知道为什么都加粗了我还没看见
noip32的更多相关文章
随机推荐
- ctf常见编码形式(罗师傅)
https://zhuanlan.zhihu.com/p/30323085 这是原链接 ASCII编码 •ASCII编码大致可以分作三部分组成: •第一部分是:ASCII非打印控制字符(参详ASCII ...
- 26. Remove Duplicates from Sorted Array*(快慢指针)
description: Given a sorted array nums, remove the duplicates in-place such that each element appear ...
- c语言:getch() getchar()
1.getchar();从键盘读取一个字符并输出,该函数的返回值是输入第一个字符的ASCII码:若用户输入的是一连串字符,函数直到用户输入回车时结束,输入的字符连同回车一起存入键盘缓冲区.若程序中有后 ...
- 学前端的第一门语言HTML
学前端最终要做的就是制作各种各样的网页,html就相当于网页的骨架,所以我们学习前端的第一步就是先学html,接下来学习什么是html. 什么是HTML? HTML指的是超文本标记语言(Hyper T ...
- 11. Linux从入门到进阶
课程大纲 • Linux简介 • Linux基础 • Linux常用命令 • Shell编程&awk
- 答读者问(1):非模式物种找marker;如何根据marker定义细胞类型
下午花了两个小时回答读者的疑问,觉得可以记录下来,也许能帮到一部分人. 第一位读者做的是非模式物种的单细胞. 一开始以为是想问我非模式物种的marker基因在哪儿找,读者朋友也提到了blast 研究的 ...
- 微信小程序云开发-云函数-初始化云函数环境
一.新建云函数文件夹 新建的云函数文件夹,命名为cloud,该文件夹一定要与pages文件夹同级.此时该文件夹的前面没有云朵的标识. 二.配置project.config.json文件 在proje ...
- MYSQL时间戳和日期相互转换 笔记整理
相关函数: date_format(date, format) 函数,MySQL日期格式化函数date_format() unix_timestamp() 函数 str_to_date(str, fo ...
- Oracle常用SQL语句大全
常用Oracle数据库SQL语句汇总. 1.常用操作 --清空回收站purge recyclebin;--查询回收站select * from recyclebin--查询Oracle版本信息sele ...
- (6java)计算机语言发展史
(6java)计算机语言发展史 机器语言: 程序是0和1的组合,比如:0000.0001.1100110 汇编语言: 程序比机器语言好理解一点点 高级语言: 比较适合老美,苦了英语差的孩子们了,哈哈. ...