uva1228 Integer Transmission

175 篇文章 0 订阅
137 篇文章 0 订阅

You’re transmitting an n -bits unsigned integer k through a simulated
network. The i -th bit counting from left is transmitted at time i
(e.g. 4-bit unsigned integer 5 is transmitted in this order: 0-1-0-1).
The network delay is modeled as follows: if a bit is transmitted at
time i , it may arrive at as early as i + 1 and as late is i + d + 1 ,
where d represents the maximal network delay. If more than one bit
arrived at the same time, they could be received in any order.

For example, if you’re transmitting a 3-bit unsigned integer 2 (010)
for d = 1 , you may receive 010, 100 (first bit is delayed) or 001
(second bit is delayed).

Write a program to find the number of different integers that could be
received, and the smallest/largest ones among them.

Input

The input contains several test cases. Each case consists of three
integers n, d, k (1 n 64, 0 d n, 0 k < 2n) ,
the number of bits transmitted, the maximal network delay, and the
integer transmitted. The last test case is followed by a single zero,
which should not be processed.

Output

For each test case, print the case number and the number of different
integers that could be received, followed by the minimal and maximal
one among them.

首先可以确定,0和1自己之间的顺序没有关系,需要调整的只是0和1之间的顺序。
比较好解决的是最大值/最小值,贪心地把0/1放在后面即可。
用dp[i][j]表示接受了i个0和j个1的方案数,考虑接下来接收的是0还是1。如果第j+1个1可以放在第i+1个0后头,那下一位就可以接收0,也就是dp[i+1][j]+=dp[i][j]。接收1同理。

#include<cstdio>
#include<cstring>
#include<vector>
#include<iostream>
#include<algorithm>
using namespace std;
#define LL unsigned long long
int p0[100],p1[100],cnt0,cnt1,n,d;
LL k,dp[100][100];
vector<int> v[100];
bool cmp(int a,int b)
{
    return a>b;
}
void init()
{
    int i;
    cnt0=cnt1=0;
    for (i=n-1;i>=0;i--)
      if (k&(1LL<<i))
        p1[++cnt1]=-i;
      else
        p0[++cnt0]=-i;
}
LL count()
{
    int i,j;
    memset(dp,0,sizeof(dp));
    dp[0][0]=1;
    for (i=0;i<=cnt0;i++)
      for (j=0;j<=cnt1;j++)
      {
        if (i<cnt0&&(j==cnt1||p1[j+1]+d>=p0[i+1]))
          dp[i+1][j]+=dp[i][j];
        if (j<cnt1&&(i==cnt0||p0[i+1]+d>=p1[j+1]))
          dp[i][j+1]+=dp[i][j];
      }
    return dp[cnt0][cnt1];
}
LL findmin()
{
    int i,j;
    for (i=n-1;i>=0;i--)
      v[i].clear();
    for (i=n-1;i>=0;i--)
      if (k&(1LL<<i))
        v[max(0,i-d)].push_back(1);
      else
        v[i].push_back(0);
    LL ret=0;
    for (i=n-1;i>=0;i--)
    {
        sort(v[i].begin(),v[i].end());
        for (j=0;j<v[i].size();j++)
          ret=ret*2+v[i][j];
    }
    return ret;
}
LL findmax()
{
    int i,j;
    for (i=n-1;i>=0;i--)
      v[i].clear();
    for (i=n-1;i>=0;i--)
      if (k&(1LL<<i))
        v[i].push_back(1);
      else
        v[max(0,i-d)].push_back(0);
    LL ret=0;
    for (i=n-1;i>=0;i--)
    {
        sort(v[i].begin(),v[i].end(),cmp);
        for (j=0;j<v[i].size();j++)
          ret=ret*2+v[i][j];
    }
    return ret;
}
int main()
{
    int K=0;
    while (cin>>n>>d>>k)
    {
        init();
        cout<<"Case "<<++K<<": "<<count()<<" "<<findmin()<<" "<<findmax()<<endl;
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值