Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 3906   Accepted: 1924

Description

Eva has a balance with 20 poises. The weights of the poises are 1, 3, 9, 27,...,3^19. Eva asserts that she has a way to measure any object whose weight is an integer from 1 to (3^20-1)/2. Assuming that Eva has placed an object with the weight in this range on the left tray of the balance, your task is to place the proper poises on the proper trays so as to weigh the object out.

Input

The first line is an integer T (1 <= T <= 20), which shows the number of the test cases. Each of the following T lines contains an integer W (1 <= W <= (3^20-1)/2), expressing the weight of an object.

Output

For each test case print a line, showing the weights of the poises on the left tray and the right tray. Use a space to separate the left tray and the right tray. The poises on the same tray are arranged in the increasing order, and a comma separates every two of them. If there is no poise on the tray, output "empty".

Sample Input

3
9
5
20

Sample Output

empty 9
1,3 9
1,9 3,27

Source

#include <iostream>
#include <string.h>
#include <stdio.h> using namespace std; int main()
{
int data[]; ///存打表的数的
int ans[]; ///存输出的数的
int a[]; ///存三进制数的
for(int i=,n=; i<=; i++,n*=)
data[i]=n; int t;
scanf("%d",&t);
while(t--)
{
int nn;
scanf("%d",&nn);
memset(ans,,sizeof(ans));
memset(a,,sizeof(a));
int cnt=;
while(nn)
{
a[++cnt]=nn%;
nn/=;
}
for(int i=; i<=cnt; i++)
{
if(a[i]==) a[i+]++,a[i]=-;
if(a[i]==) a[i+]++,a[i]=;
}
if(a[cnt+]) cnt++; bool flag=false;
int tp=;
for(int i=; i<=cnt; i++)
{
if(a[i]<)
flag=true,ans[++tp]=data[i-];
}
if(!flag)
printf("empty ");
else
{
for(int i=; i<tp; i++)
{
printf("%d,",ans[i]);
}
printf("%d ",ans[tp]);
}
flag=false;
tp=;
for(int i=; i<=cnt; i++)
{
if(a[i]>)
flag=true,ans[++tp]=data[i-];
}
if(!flag)
{
printf("empty ");
}
else
{
for(int i=; i<tp; i++)
{
printf("%d,",ans[i]);
}
printf("%d",ans[tp]);
}
puts("");
}
return ;
}

分析:本题用到了很冷的平衡三进制算法

首先我们可以将数n分解成三进制加法形式

e.g   102=(01201) i.e  102=0*3(0)+1*3(1)+2*3(2)+0*3(3)+1*3(4)

有如下转换:

2*3(n)=(3-1)*3(n)=3(n+1)-3(n)

这样,我们便可以用-1,0,1表示一个数字。同时1,-1也构成了两堆三进制数。

\(^o^)/,问题解决。

p.s:有一些细节我在代码中注释了。

#include "iostream"
#include "cstring"
#include "cstdlib"
#include "cstdio"
#include "cmath"
using namespace std;
int n;
int a[100001],tp;
int sto[10001],cnt;
int data[100];
int main(){
//freopen("ans.txt","r",stdin);
//freopen("1.txt","w",stdout);
for (int i=0,tt=1;i<=99;i++,tt*=3) data[i]=tt;
int cases;scanf("%d",&cases);
while(cases--){
scanf("%d",&n);tp=0;
memset(sto,0,sizeof sto); //忘了清数组,贡献2wa
memset(a,0,sizeof a);
while(n){
a[++tp]=n%3;
n/=3;
}
while(1);
for (int i=1;i<=tp;i++){ //转化为平衡三进制。
if (a[i]==2) a[i]=-1,a[i+1]++;
if (a[i]==3) a[i]=0,a[i+1]++;
}
bool flag=false;
if (a[tp+1]) tp++; //如果加过了,tp++
cnt=0;
for (int i=1;i<=tp;i++) //处理减数
if (a[i]<0) flag=true,sto[++cnt]=data[i-1];
if (!flag) printf("empty "); //不存在减数
else {for (int i=1;i<cnt;i++) printf("%d,",sto[i]);printf("%d ",sto[cnt]);}
flag=false;cnt=0;
for (int i=1;i<=tp;i++) //处理减数
if (a[i]>0) flag=true,sto[++cnt]=data[i-1];
if (!flag) printf("empty"); //不存在被减数,其实就是对0,0这个case的处理。
else {for (int i=1;i<cnt;i++) printf("%d,",sto[i]);printf("%d",sto[cnt]);}
a[tp]=0;
puts("");
} return 0;
}
/*
301354
3,729,59049,177147 1,9,27,243,6561,531441
*/

poj 1702 三进制问题的更多相关文章

  1. poj 1308Bugs Integrated, Inc. [三进制状压]

    题目链接[http://poj.org/problem?id=1038] 题意: 给出一个N*M大小的图,图中有K个坏点.N (1 <= N <= 150), M (1 <= M & ...

  2. POJ 1038 Bugs Integrated, Inc.(DFS + 三进制状压 + 滚动数组 思维)题解

    题意:n*m方格,有些格子有黑点,问你最多裁处几张2 * 3(3 * 2)的无黑点格子. 思路:我们放置2 * 3格子时可以把状态压缩到三进制: 关于状压:POJ-1038 Bugs Integrat ...

  3. hdu 3001 Travelling 经过所有点(最多两次)的最短路径 三进制状压dp

    题目链接 题意 给定一个\(N\)个点的无向图,求从任意一个点出发,经过所有点的最短路径长度(每个点至多可以经过两次). 思路 状态表示.转移及大体思路 与 poj 3311 Hie with the ...

  4. 三进制状压 HDOJ 3001 Travelling

    题目传送门 题意:从某个点出发,所有点都走过且最多走两次,问最小花费 分析:数据量这么小应该是状压题,旅行商TSP的变形.dp[st][i]表示状态st,在i点时的最小花费,用三进制状压.以后任意进制 ...

  5. hdu 3001 Travelling(状态压缩 三进制)

    Travelling Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  6. HDU - 3001 Travelling 状压dp + 三进制 [kuangbin带你飞]专题二

    终于刷完搜索专题了. 题意:给定n个城市,每个城市参观不能超过两次,两个城市之间有道路通过需要花费X,求通过能所有城市的最小花费. 思路:每个城市有三个状态0,1,2,可用三进制存储所有城市的访问状态 ...

  7. hdu4064 三进制状态压缩 好题!

    还不太会做这类题,总之感觉有点难啊. 用深搜代替打表求出一行所有的可行状态,注意要进行剪枝 这是自己理解的代码,但是tle了 #include<bits/stdc++.h> using n ...

  8. hdu 3001 Travelling (三进制)【状压dp】

    <题目链接> 题目大意: 给出n个点和m条边,求经过所有点所需的最小花费,每个点最多经过两次. 解题分析: TSP问题类型,由于此题每个点有三种状态,所以采用三进制状态压缩,0.1.2 分 ...

  9. Gym 101194L / UVALive 7908 - World Cup - [三进制状压暴力枚举][2016 EC-Final Problem L]

    题目链接: http://codeforces.com/gym/101194/attachments https://icpcarchive.ecs.baylor.edu/index.php?opti ...

随机推荐

  1. Noip2016提高组 组合数问题problem

    Day2 T1 题目大意 告诉你组合数公式,其中n!=1*2*3*4*5*...*n:意思是从n个物体取出m个物体的方案数 现给定n.m.k,问在所有i(1<=i<=n),所有j(1< ...

  2. codeforces 704A (队列模拟) Thor

    题目:这里 题意:n个app,q个操作,当操作数type为1的时候表示y这个app推送了你一条消息,当操作数type为2的时候表示将y这个app已推送的所有消息都读完,当操作数为3的时候 表示将已经推 ...

  3. 各大门户网站的css初始化代码

    腾讯QQ官网 css样式初始 body,ol,ul,h1,h2,h3,h4,h5,h6,p,th,td,dl,dd,form,fieldset,legend,input,textarea,select ...

  4. 使用swfobject.js时样式及传参的问题

    swfobject.js 最近需要在项目中引入swf文件. 最初的写法: <div id="recorderDiv"> <object id="reco ...

  5. 使用cookie实现计数器功能

    思路是:若第一次访问,创建cookie.若访问次数大于一,则先读出cookie值赋给一个值,然后再重新写入cookie. <?php if(!isset($_COOKIE['num'])){ $ ...

  6. 2016年iOS技术圈回顾

    2016年同2015年一样,在我还没有做好心理准备的时候,一晃神就到了年底.年关将近,不知诸君心情如何,年初的规划实现了多少,来年的计划又是否已有了眉目.年过三十的Peak君感觉年关是越来越难过了,越 ...

  7. [python] 创建临时文件-tempfile模块

    This module generates temporary files and directories. It works on all supported platforms.In versio ...

  8. python学习之路-day6-面向对象

    一.面向对象学习 特性 class类 一个类即是对一类拥有相同属性的对象的抽象.蓝图.原型.在类中定义了这些对象的都具备的属性.共同的方法. 面向过程编程和面向对象编程: 面向过程编程:使用一系列的指 ...

  9. 类Collections的静态方法

    类Collections的静态方法 此类完全由在 collection 上进行操作或返回 collection 的静态方法组成. 排序 static <T extends Comparable& ...

  10. 简单jquery实现select三级联动

    简单的jquery实现select三级联动 代码如下: <!DOCTYPE html> <html> <head> <meta charset="u ...