Codeforces Round #213 (Div. 1)

http://codeforces.com/contest/364

A. Matrix

考虑一个矩形(x, y, z, t)的sum和等于 (s[x] + s[x+1] + ... +s[y]) * (s[z] + s[z+1] + ... s[t]),所以处理出所有子序列的和即可,有些小细节要注意比如说0,比赛时候囧了。。

// Author : JayYe  Created Time: 2013-11-19 23:47:55
#include 
  
  
   
   
#include 
   
   
    
    
#include 
    
    
#include 
     
     
      
      
using namespace std;
typedef __int64 ll;

const int maxn = 4000 + 5;

char s[maxn];
ll a[maxn][maxn];
ll b[maxn*maxn];
map
      
      
        mp; int main() { ll n; scanf("%I64d%s", &n, s + 1); int len = strlen(s + 1), tot = 0; for(int i = 1;i <= len; i++) { a[i][i] = s[i] - '0'; b[tot++] = a[i][i]; mp[a[i][i]]++; for(int j = i+1;j <= len; j++) { a[i][j] = a[i][j-1] + s[j] - '0'; b[tot++] = a[i][j]; mp[a[i][j]]++; } } ll ans = 0; for(int i = 0;i < tot; i++) { if(n == 0) { if(b[i] == 0) ans += tot; else ans += mp[0]; } else if(b[i] != 0 && n % b[i] == 0) { // printf("%d %d\n", b[i], mp[n/b[i]]); ans += mp[n / b[i]]; } } printf("%I64d\n", ans); return 0; } 
      
     
     
   
   
  
  


B. Free Market

一直不知道怎么处理好只能拿一个集合去交换没有交集的集合,其实对于两个不同的状态a, b,如果b - a <= d,那么必然可是由a状态一步转移到b状态,如果a、b没有交集,那就直接用a的集合换b的集合,如果有交集,其实不要交换相同元素即可。所以首先背包把所有的可行状态处理出来,然后每天贪心取到最多能取的 <= d的下一个状态,于是就这样解决了。。还是太弱了


// Author : JayYe  Created Time: 2013-11-20 18:56:53
#include 
   
   
    
    
#include 
    
    
     
     
#include 
     
     
      
      
using namespace std;

const int maxn = 1000000 + 10;

bool vis[maxn];
int b[maxn], a[55];

int main() {
    int n, d;
    scanf("%d%d", &n, &d);
    for(int i = 1;i <= n; i++) {
        scanf("%d", &a[i]);
    }
    sort(a + 1, a + n + 1);
    vis[0] = true;
    int pre = 0;
    for(int i = 1;i <= n; i++) {
        bool flag = false;
        for(int j = pre;j >= 0; j--) if(vis[j] && a[i] - j <= d) {
            flag = true;
            break;
        }
        if(!flag)    break;
        for(int j = pre;j >= 0; j--) if(vis[j])
            vis[j + a[i]] = true;
        pre += a[i];
    }
    int tot = 0, ans = 0;
    for(int i = 0;i <= pre;i ++) if(vis[i])
        b[tot++] = i;
    if(tot == 1)    return puts("0 0"), 0;
    pre = 0;
    for(int i = 0;i < tot; i++) {
        if(pre + d < b[i]) {
            ans++; pre = b[i-1];
        }
    }
    ans++;
    printf("%d %d\n", b[tot-1], ans);
    return 0;
}

     
     
    
    
   
   

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值