【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 ...
随机推荐
- 201621123050 《Java程序设计》第11周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2. 书面作业 本次PTA作业题集多线程 1. 源代码阅读:多线程程序BounceThread 1.1 BallR ...
- 第201621123043 《Java程序设计》第13周学习总结
1. 本周学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 2. 为你的系统增加网络功能(购物车.图书馆管理.斗地主等)-分组完成 系统还在创建中..... 为了让你 ...
- Linux进程管理之task_struct结构体
进程是处于执行期的程序以及它所管理的资源(如打开的文件.挂起的信号.进程状态.地址空间等等)的总称.注意,程序并不是进程,实际上两个或多个进程不仅有可能执行同一程序,而且还有可能共享地址空间等资源. ...
- RxSwift 函数响应式编程
Max 在 Boston 上学,在 San Francisco 工作,是一名软件工程师及创业者.当他还在高中的时候就在一家创业公司工作了,他非常喜欢使用 iOS.Android 以及 JavaScri ...
- js回顾(DOM中标签的CRUD,表格等)
01-DOM中的创建和添加标签 02-删除替换克隆标签 03-全选全不选反选 04-新闻字体 05-表格增删 06-动态生成表格 07-表格隔行变色 08-左到右右到左(将左边的标签移动到右边) 09 ...
- 如何设置eclipse 右键new的菜单
如何设置eclipse 右键new的菜单 在使用eclipse进行开发的时候,开发人员一般使用File-new来创建项目或文件,但常常发现,默认右键new选项里很多选项极少会用到,而一些常用的选项又没 ...
- Linux系统的基本使用
曾经在网上看到一个一篇文章,说到了Linux学习的入门与学习技巧,也就是:初学者可以自己安装虚拟机,然后把linux常用命令例如cd.ls.chmod.useradd.vi等等多练习几十遍,把自己敲打 ...
- 【webGL入门2】点线面的绘制
用js绘制webGL的点: THREE.Vector3 = function ( x, y, z ) { //用THREE声明的变量都是全局变量.this.x = x || 0;this.y = y ...
- [CodeForces 11D] A Simple Task - 状态压缩入门
状态压缩/Bitmask 在动态规划问题中,我们会遇到需要记录一个节点是否被占用/是否到达过的情况.而对于一个节点数有多个甚至十几个的问题,开一个巨型的[0/1]数组显然不现实.于是就引入了状态压缩, ...
- Java面试题——中级(下)
内部类和静态内部类的区别 内部类: 1.内部类中的变量和方法不能声明为静态的. 2.内部类实例化:B是A的内部类,实例化B:A.B b = new A().new B(). 3.内部类可以引用外部类的 ...