【NOIP2012TG】solution
D1T1(Vigenere)
题意:给你一个原串与一个密码串,问你按照题意规则加密后的密文。
解题思路:暴力模拟。
#include <stdio.h>
int k[],c[],u1[],u2[];
void read(int*a,int*b){
char c;
while(c=getchar(),c>='a'&&c<='z'||c>='A'&&c<='Z')
if(c>='a'&&c<='z')a[++a[]]=c-'a';
else a[++a[]]=c-'A',b[a[]]=;;
}
int main(){
read(k,u1);read(c,u2);int j=;
for(int i=;i<=c[];i++)
{
j++;if(j==k[]+)j=;
c[i]=(c[i]-k[j]+)%;
}
for(int i=;i<=c[];i++)
if(u2[i]==)putchar(c[i]+'A');
else putchar(c[i]+'a');
}
D1T2(game)
题意:n个物品,每个物品有2个val,然后按照题目当中的价值计算方式计算,求使得价值最高的物品最小的价值。
解题思路:考虑最后一个大臣,显然他很可能是金币最多的人。我们要让他的金币尽量的少。之前的大臣左手的数肯定会乘起来,所以我们要使S/A/B尽量的大。(设S 是左手所有数的乘积),即让A*B尽量的大。选完最后一个后,我们把他踢掉,然后再找一个最后的大臣。如此往复,相当于就是对A*B排序。然后就直接按照上述思路进行处理,剩下的就是高精度,压4位就可以直接计算了。
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define MN 1005
struct sv{
int a,b;
inline bool operator <(const sv &y)const{
return a*b<y.a*y.b;
}
}t[MN];
struct hpc{
int num[MN],len;
inline bool operator <(const hpc &b)const{
if (len^b.len) return len<b.len;
for (int i=len-; i>=; --i)
if (num[i]^b.num[i]) return num[i]<b.num[i];
return ;
}
inline hpc operator *(int b)const{
hpc ans;int &leng=ans.len;
memset(ans.num,,sizeof(ans.num));
for (int i=; i<len; ++i){
ans.num[i]+=num[i]*b;ans.num[i+]+=ans.num[i]/;
ans.num[i]%=;
}ans.len=len;
for (; ans.num[leng]; ++leng){
ans.num[leng+]=ans.num[leng]/;ans.num[leng]%=;
}return ans;
}
inline hpc operator /(int b)const{
hpc ans;int &leng=ans.len;
memset(ans.num,,sizeof(ans.num));
for (int i=len-; i; --i){
ans.num[i-]+=(ans.num[i]+num[i])%b*;
ans.num[i]=(ans.num[i]+num[i])/b;
}
ans.num[]=(ans.num[]+num[])/b;
for (ans.len=len; !ans.num[leng-]; --leng);
return ans;
}
inline void print(){
printf("%d",num[len-]);
for (int i=len-; i>=; --i) printf("%.4d",num[i]);
}
}sum,res;int n;
int main(){
scanf("%d",&n);
for (int i=;i<=n;i++){
scanf("%d%d",&t[i].a,&t[i].b);
}sum.num[]=t[].a;sum.len=;
std::sort(t+,t+n+);
for (int i=;i<=n;i++){
hpc tmp=sum/t[i].b;
if (res<tmp) res=tmp;
sum=sum*t[i].a;
}res.print();
}
D1T3(drive)
题意:有n个点,每个点有高度,两个点的距离定义为高度差的绝对值(高度越小的默认越距离相对较小)。有2个人,1个人走最近的路,另一个人走第二近的路,现在这2人轮流开车,问:(I)给定时间t,问选哪个起点两人走的路程比值最小。(II)给定起点a与时间t,问走完后2人各自走了多少。
解题思路:首先考虑如何处理距离的问题,我们需要做到的是给定一个高度,在其左右2边进行查找,显然c++STL中的set是可以较为方便的实现的。
接下来考虑如何解决问题:首先我们将轮流走一次压缩为1步,然后倍增求出走x步的距离,然后对于每次询问就只需要倍增查找即可。(I)就是暴力扫一遍找答案,(II)就是裸的询问。时间效率\( O((n+m) \log n) \)
#include <stdio.h>
#include <algorithm>
#include <set>
#define MN 100005
#define lg 16
#define ll long long
#define inf 1e16
#define abs(a) (((a))<0?(-1*(a)):(a))
struct point{
int no,h;
bool operator <(const point &b)const{
return h<b.h;
}
}a[MN];
struct cmpp{
int no,dis;
bool operator <(const cmpp &b)const{
return dis<b.dis||(dis==b.dis&&a[no].h<a[b.no].h);
}
}tmp[];
using std::set; set<point> pt;
int n,m,x0,na[MN],nb[MN],ans;
ll fa[MN][lg+],da[MN][lg+],db[MN][lg+],ansa=inf,ansb=0ll;
inline int in(){
int x=,f=;char ch=getchar();
while(ch<''||ch>'') f=ch=='-'?-:,ch=getchar();
while(ch>=''&&ch<='') x=x*+ch-'',ch=getchar();
return x*f;
}
inline void prework(int k){
set<point>::iterator it=pt.find(a[k]);
register int j=;
if (it!=pt.begin()){
--it;tmp[++j].no=it->no,tmp[j].dis=abs(it->h-a[k].h);
if (it!=pt.begin()){
--it;tmp[++j].no=it->no,tmp[j].dis=abs(it->h-a[k].h);++it;
}++it;
}
if ((++it)!=pt.end()){
tmp[++j].no=it->no,tmp[j].dis=abs(it->h-a[k].h);
if ((++it)!=pt.end()){
tmp[++j].no=it->no,tmp[j].dis=abs(it->h-a[k].h);
}
}
std::sort(tmp+,tmp++j);
nb[k]=tmp[].no;
if (j==) return;
na[k]=tmp[].no;
}
inline void getans(int u,int t,ll &ta,ll &tb){
for (register int i=lg; i>=; --i)
if (fa[u][i]&&da[u][i]+db[u][i]<=t){
ta+=da[u][i],tb+=db[u][i];
t-=da[u][i]+db[u][i];u=fa[u][i];
}
if (da[u][]<=t) ta+=da[u][];
}
void init(){
n=in();for (int i=; i<=n; ++i) a[i].h=in(),a[i].no=i;
for (register int i=n; i; --i) {pt.insert(a[i]);if (i!=n) prework(i);}
}
void st(){
for (register int i=; i<=n; ++i){
register int p1=na[i],p2=nb[na[i]];
da[i][]=p1?abs(a[p1].h-a[i].h):;
db[i][]=p2?abs(a[p2].h-a[p1].h):;
fa[i][]=p2;
}
for (int j=; j<=lg; ++j)
for (register int i=; i<=n; ++i){
fa[i][j]=fa[fa[i][j-]][j-];
da[i][j]=da[i][j-]+da[fa[i][j-]][j-];
db[i][j]=db[i][j-]+db[fa[i][j-]][j-];
}
}
void solve(){
st();x0=in();
for (register int i=; i<=n; ++i){
register ll ta=0ll,tb=0ll;
getans(i,x0,ta,tb);
if (tb&&(!ans||ansa*tb>ansb*ta))
ans=i,ansa=ta,ansb=tb;
}
printf("%d\n",ans);m=in();
for (register int i=; i<=m; ++i){
register int x=in(),t=in();
register ll ta=0ll,tb=0ll;
getans(x,t,ta,tb);
printf("%lld %lld\n",ta,tb);
}
}
int main(){init();solve();return ;}
D2T1(mod)
题意:看题目。
解题思路:裸的exgcd,注意一下答案要取最小正整数。
#include <stdio.h>
inline void exgcd(int a,int b,int &x,int &y){
if (!b){x=,y=; return;}
exgcd(b,a%b,x,y);
int t=x;x=y;y=t-a/b*y;
}
int main(){
int a,b,x,y;
scanf("%d%d",&a,&b);
exgcd(a,b,x,y);
x=(x+b)%b;printf("%d",x);
}
D2T2(classroom)
题意:有n天,每天有r[i]间教室,有m个任务,这个任务占用一个时间段中的若干间教室,问按顺序满足最多可以满足多少间。
解题思路:二分答案,然后差分统计第i天借了教室的数量,check即可。时间效率:\( O(n\log n) \)
#include <stdio.h>
#include <string.h>
#define MN 1000005
#define mid (l+r>>1)
int cf[MN],n,m,s[MN],t[MN],d[MN],r[MN];
inline int in(){
int x=,f=;char ch=getchar();
while(ch<''||ch>'') f=ch=='-'?-:,ch=getchar();
while(ch>=''&&ch<='') x=x*+ch-'',ch=getchar();
return x*f;
}
inline bool check(int ans){
memset(cf,,sizeof(cf));
for (register int i=; i<=ans; ++i)
cf[s[i]-]+=d[i],cf[t[i]]-=d[i];
register int tmp=cf[];
for (register int i=; i<=n; tmp+=cf[i++])
if (tmp>r[i]) return ;
return ;
}
void init(){
n=in(),m=in();
for (int i=; i<=n; ++i) r[i]=in();
for (register int i=; i<=m; ++i) d[i]=in(),s[i]=in(),t[i]=in();
}
void solve(){
int l=,r=m;
for (;l<r; check(mid)?l=mid+:r=mid);
if (r==m) puts("");
else printf("-1\n%d",r);
}
int main(){init();solve();return ;}
D2T3(blockade)
题意:在一棵树上,有m个可以移动的东西,树的边有权值,若根到某个节点上有东西,那么就无法遍历到某个节点,问无法遍历到所有叶节点的最小时间。
解题思路:首先倍增预处理,然后考虑二分答案,紧接着对于二分出来的答案,让所有的东西在时限内尽可能的往上爬,能爬到根节点的记录下来,接下来先dfs找出根节点的子节点子树中是否存在没有所有叶节点都无法遍历到,然后贪心即可。时间效率 \( O(n\log n + (m\log {mn} + n)\log Ans) \).
#include <stdio.h>
#include <algorithm>
#include <string.h>
#define MN 50005
#define lg 15
#define ll long long
#define v edge[i].to
#define mid (l+r>>1)
char B[<<],*S=B,C;int X;
inline int in(){
while((C=*S++)<''||C>'');
for(X=C-'';(C=*S++)>=''&&C<='';)X=(X<<)+(X<<)+C-'';
return X;
}
struct edg{
int to,nxt,val;
bool friend operator <(const edg &a,const edg &b){
return a.val<b.val;
}
}edge[MN<<],ste[MN];
struct tas{
int tim,lstpos;
bool friend operator <(const tas &a,const tas &b){
return a.tim<b.tim;
}
}task[MN];
int head[MN],n,m,l,r,cnt,fa[MN][lg+],cntt,pos[MN],count;
bool vis[MN],isleaves[MN],used[MN];ll dis[MN];
inline void ins(int x,int y,int val){edge[++cnt].to=y,edge[cnt].nxt=head[x],head[x]=cnt,edge[cnt].val=val;}
inline void pre(int u,int f,ll d){
fa[u][]=f,dis[u]=d;register bool b=;
for (register int i=head[u]; i; i=edge[i].nxt)
if (v!=f) b=,pre(v,u,d+edge[i].val);
if (b) isleaves[u]=;
}
void init(){
fread(B,,<<,stdin);n=in();
for (int i=; i<n; ++i){
register int x=in(),y=in(),val=in();
ins(x,y,val);ins(y,x,val);
if (x==||y==)
ste[++cntt].to=x==?y:x,ste[cntt].val=val;
}
std::sort(ste+,ste+cntt+);
m=in();if (m<cntt){puts("-1");return;}
for (register int i=; i<=m; ++i) pos[i]=in();
pre(,,);
for (int j=; j<=lg; ++j)
for (register int i=; i<=n; ++i)
fa[i][j]=fa[fa[i][j-]][j-];
}
inline bool dfs(int u){
register bool p=;if (vis[u]) return ;
if (isleaves[u]) return ;
for (register int i=head[u]; i; i=edge[i].nxt)
if (v!=fa[u][]) p&=dfs(v);
return vis[u]=p;
}
inline bool uptree(int no,int tim){
register int u=pos[no];
for (register int i=lg; i>=; --i)
if (fa[u][i]>&&dis[pos[no]]-dis[fa[u][i]]<=tim) u=fa[u][i];
if (fa[u][]==&&dis[pos[no]]<tim) {
task[++count].lstpos=u,task[count].tim=tim-dis[pos[no]];
}else vis[u]=;
}
inline bool check(int ans){
count=;memset(vis,,sizeof(vis));
for (register int i=; i<=m; ++i) uptree(i,ans);
dfs();std::sort(task+,task+count+);
register int p=;
for (register int i=; i<=count; ++i)
if (!vis[task[i].lstpos]) vis[task[i].lstpos]=;
else{
while(vis[ste[p].to]&&p<=cntt) ++p;if (p>cntt) return ;
if (task[i].tim>=ste[p].val) vis[ste[p].to]=;
}
while(vis[ste[p].to]) ++p;return p>cntt;
}
void solve(){
int l=,r=1e9;
for (;l<r; check(mid)?r=mid:l=mid+);
printf("%d",r);
}
int main(){init();solve();return ;}
【NOIP2012TG】solution的更多相关文章
- about家庭智能设备部分硬件模块功能共享【协同工作】solution
本人设备列表: Onda tablet {Android} wifi Desktop computer {win7.centos7} 外接蓝牙adapter PS interface 键盘.鼠标{与同 ...
- 【leetcode】solution in java——Easy1
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6409067.html 1:Hamming distance The Hamming distance betw ...
- 【436】Solution for LeetCode Problems
Coding everyday. ^_^ 1. Two Sum 重点知识:指针可以存储数值,通过 malloc 新建数组 int* returnSize:Size of the return arra ...
- 【NOIP2014TG】solution
链接:https://www.luogu.org/problem/lists?name=&orderitem=pid&tag=83|31 D1T1(rps) 题意:给你一个周期,以及胜 ...
- 【NOIP2016TG】solution
传送门:https://www.luogu.org/problem/lists?name=&orderitem=pid&tag=83%7C33 D1T1(toys) 题意:有n个小人, ...
- 【NOIP2015TG】solution
链接:https://www.luogu.org/problem/lists?name=&orderitem=pid&tag=83%2C32 D1T1(magic) 题意:看题目.. ...
- 【NOIP2013TG】solution
链接:https://www.luogu.org/problem/lists?name=&orderitem=pid&tag=83%2C30 D1T1:转圈游戏(circle) 题意: ...
- 【NOIP2011TG】solution
老师最近叫我把NOIPTG的题目给刷掉,于是就开始刷吧= = 链接:https://www.luogu.org/problem/lists?name=&orderitem=pid&ta ...
- 【leetcode】solution in java——Easy5
转载请注明原文地址: 21:Assign Cookies Assume you are an awesome parent and want to give your children some co ...
随机推荐
- Beta冲刺NO.3
Beta冲刺 第三天 1. 昨天的困难 1.昨天的困难主要集中在对Ajax的使用上,不熟悉这种语法,所以也就浪费了时间,导致昨天的批量删除没有完全完成. 2.由于之前的网页构造style很乱,导致修改 ...
- Java作业-多线程
未完成,占位以后补 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 书面作业 本次PTA作业题集多线程 源代码阅读:多线程程序BounceThread 1.1 Ball ...
- 前端之bootstrap模态框
简介:模态框(Modal)是覆盖在父窗体上的子窗体.通常,目的是显示来自一个单独的源的内容,可以在不离开父窗体的情况下有一些互动.子窗体可提供信息.交互等. Modal简介 Modal实现弹出表单 M ...
- zookeeper入门系列:paxos协议
上一章讨论了一种强一致性的情况,即需要分布式事务来解决,本章我们来讨论一种最终一致的算法,paxos算法. paxos算法是由大牛lamport发明的,关于paxos算法有很多趣事.比如lamport ...
- thinkphp框架调用类不存在的方法
thinkphp框架调用类不存在的方法调用类不存在的方法,不会报错,但是也不会执行,这是根据tp框架里面的一个魔术方法,框架里面一共才十几个魔术方法
- linux——网络基础
装完linux系统要对网络(ip地址,子网掩码,网关,DNS)进行配置,才能连接网络 一,开启网卡eth0 CentOS显示没有网卡(eth0) 2.设置静态IP vim /etc/sysconfig ...
- python 字符串的方法
capitalize() 把字符串的第一个字符改为大写 casefold() 把整个字符串的所有字符改为小写 center(width) 将字符串居中,并使用空格填充至长度 width 的新字符串 c ...
- GIT入门笔记(1)- Git的基本概念
一.概念和定义 1.git是什么 许多人习惯用复制整个项目目录的方式来保存不同的项目版本,或许还会改名加上备份时间以示区别.这么做唯一的好处就是简单.不过坏处也不少:有时候会混淆所在的工作目录,一旦弄 ...
- GIT入门笔记(20)- git 开发提交代码过程梳理
git开发提交流程新项目开发,可以直接往master上提交老项目维护,可以在分支上修改提交,多次add和commit之后,也可以用pull合并主干和本地master,解决冲突后再push 1.检出代码 ...
- SSM登陆注册
package com.coingod.controller; import java.io.IOException;import java.io.PrintWriter;import java.ut ...