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. treap树模板

    ///treap树模板 typedef struct Node ///节点的结构体 { Node *l,*r; int val,pri; ///节点的值和优先级 int sz; ///节点子树的节点数 ...

  2. Reverse链表 递归实现

    #include<iostream> struct node{ int payload; node* next; }; void bianli(node* head){ node* ite ...

  3. Matlab(2) -- Find()函数

    转自:http://www.matlabsky.com/thread-4228-1-1.html find函数:用于查询非零元素的行和列标志 语法: ind = find(X) ind = find( ...

  4. es6中添加块级作用域的目的

    原本只有函数作用域和全局作用域两种,这就导致出现很多不方便的地方: 1)for循环问题:在看js高程的时候,纠结在第七章好久,就是一个这样的实例 function createFunctions(){ ...

  5. 20145226夏艺华 《Java程序设计》第0周学习总结

    关于师生关系: 学生和老师之间我觉得关系时多元化的,不能拘泥于单独的一种关系:灌输与被灌输,教授与被教授--我认为,在不同的课程阶段,师生之间的关系都可以发生变化.前期的老师更像是一个指路的人,而在入 ...

  6. Charles

    1. charles使用教程指南+客户端弱网测试:http://blog.csdn.net/anualday/article/details/51423457 2.使用Charles对Https请求进 ...

  7. sql操作

    SQL Server 存储过程 Transact-SQL中的存储过程,非常类似于Java语言中的方法,它可以重复调用.当存储过程执行一次后,可以将语句缓存中,这样下次执行的时候直接使用缓存中的语句.这 ...

  8. hdoj 1002 A+B(2)

    Problem Description I have a very simple problem for you. Given two integers A and B, your job is to ...

  9. 基于ArcGIS Viewer for Flex开发的一款跨平台的应用程序

    特点: 1.基于ArcGIS Viewer for Flex开发的一款跨平台的应用程序: -(IBAction) showTOC:(id)sender { if (_tocViewController ...

  10. ExecutorService中submit和execute的区别(转)

    在Java5之后,并发线程这块发生了根本的变化,最重要的莫过于新的启动.调度.管理线程的一大堆API了.在Java5以后,通过Executor来启动线程比用Thread的start()更好.在新特征中 ...