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. DOM事件机制进一步理解

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...

  2. 修改页面JS 360浏览器

    javascript:document.body.contentEditable='true'; document.designMode='on'; void 0

  3. keepalived+mysql实现双主高可用

    环境: DB1:centos6.8.mysql5.5.192.168.2.204  hostname:bogon DB2:centos6.8.mysql5.5.192.168.2.205  hostn ...

  4. HibernateTemplate的一些常用方法总结

    1:get/load存取单条数据 public Teacher getTeacherById(Long id) { return (Teacher)this.hibernateTemplate.get ...

  5. grunt配置太复杂?发布一个前端构建工具,简单高效,自动跳过未更新的文件

    做前端项目,如果没有一个自动化构建工具,手动处理那简直就是坑爹O(∩_∩)O.于是上网了解了下,grunt用的人不少,功能也挺强大.看了一下grunt的配置(包括gulp),感觉稍显复杂.当时项目结构 ...

  6. 【转载】SQL Server 2008 r2 中 SQL语句中单引号转义

    sql server有两个转义符. 默认情况下, 单引号'是字符串的边界符, 如果在字符串中包含单引号', 则必须使用两个单引号', 第1个单引号'就是转义符.

  7. windows qt 编译 boost 添加 路径

    win32-msvc2015: { contains(QMAKE_HOST.arch, x86):{ INCLUDEPATH += D:\3SDK\boost_1_61_0 LIBS += -LD:\ ...

  8. js如何找到方法在哪个js文件

    在Console窗口中输入var f = methodA.prototype.constructor;console.log(f); 网络搜索到的方法.

  9. exe文件放在其他位置

    set PATH=%PATH%;%UGII_ROOT_DIR%call "E:\ZY\exe\uds_rename_parts_mohao.exe"E:\ZY\exe\uds_re ...

  10. BOOTSTRAP定制

    1.补充:栅格系统中调整列的位置/顺序 (1)方法1:偏移量(col-*-offset-*) (2)方法2:对列进行push/pull操作 col-lg-pull-1        ~         ...