http://ac.jobdu.com/problem.php?pid=1376
给定一个整数序列,求其最接近0的连续子串和。
DP类题目,注意考虑正数负数两种情况,略复杂一些。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define N 100000
struct st {
int s;
int i;
};
int cmp(const void *a, const void *b)
{
struct st *c = (struct st *)a;
struct st *d = (struct st *)b;
if (c->s != d->s)
return c->s - d->s;
else
return c->i - d->i;
}
int main(void)
{
int n, i;
int a;
struct st sum[N];
while (scanf("%d", &n) != EOF)
{
int min = 0;
for (i=0; i<n; i++)
{
scanf("%d", &a);
if (i == 0)
{
min = a;
sum[i].s = a;
sum[i].i = i;
continue;
}
sum[i].s = sum[i-1].s + a;
sum[i].i = i;
if (abs(sum[i].s) < abs(min))
min = sum[i].s;
else if (abs(sum[i].s) == abs(min) && sum[i].s > min)
min = sum[i].s;
}
qsort(sum, n, sizeof(sum[0]), cmp);
for (i=1; i<n; i++)
{
int tmps = sum[i].s-sum[i-1].s;
int tmpi = sum[i].i-sum[i-1].i;
if (tmps < abs(min))
{
if (tmpi > 0)
min = tmps;
else
min = -tmps;
}
else if (tmps == abs(min) && min < 0)
{
if (tmpi > 0)
min = tmps;
}
}
printf("%d\n", min);
}
return 0;
}
/************************************************************** Problem: 1376 User: liangrx06 Language: C Result: Accepted Time:180 ms Memory:2304 kb ****************************************************************/
http://ac.jobdu.com/problem.php?pid=1377
如何将给定的整数序列变换成缓变序列:即任意两个相邻的元素相差均为1,第1个元素和最后一个元素相差也为1. 变换是指改变原整数序列中各元素的顺序。
#include <stdio.h>
#include <string.h>
#define N 100000
#define M 10000
int main(void)
{
int n, i, k;
int c[M+1];
int min, max;
while (scanf("%d", &n) != EOF)
{
memset(c, 0, sizeof(c));
min = M;
max = 0;
for (i=0; i<n; i++)
{
scanf("%d", &k);
min = (k < min) ? k : min;
max = (k > max) ? k : max;
c[k] ++;
}
for (i=min+1; i<max; i++)
{
c[i] -= c[i-1];
if (c[i] <= 0)
break;
}
if (c[i] == c[i-1])
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
/************************************************************** Problem: 1377 User: liangrx06 Language: C Result: Accepted Time:30 ms Memory:912 kb ****************************************************************/
http://ac.jobdu.com/problem.php?pid=1380
每个人有自己的lucky number,小A也一样。不过他的lucky number定义不一样。他认为一个序列中某些数出现的次数为n的话,都是他的lucky number。但是,现在这个序列很大,他无法快速找到所有lucky number。既然这样,他就想找到那些不是lucky number。
这类题目用位运算往往有奇效,详见代码。
#include <stdio.h>
int main()
{
int i, j, n, m, t;
int sum[32];
int result;
while(scanf("%d%d", &n, &m) != EOF)
{
for (j=0; j<32; j++)
sum[j] = 0;
for (i=0; i<m; i++)
{
scanf("%d", &t);
for (j=0; j<32 && t; j++)
{
sum[j]+=((t)&0x01);
sum[j]%=n;
t >>= 1;
}
}
result = 0;
for (j=0; j<32; j++)
{
if (sum[j] % n != 0)
result += 1<<j;
}
printf("%d\n", result);
}
return 0;
}
/**************************************************************
Problem: 1380
User: liangrx06
Language: C
Result: Accepted
Time:1450 ms
Memory:912 kb
****************************************************************/
http://ac.jobdu.com/problem.php?pid=1384
在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
二分法查找,但二维有序数组的二分法有些区别,详见代码。
#include <stdio.h>
#define N 1000
int binarySearch(int a[N][N], int is, int ie, int js, int je, int k)
{
if (is > ie || js > je)
return 0;
if (is == ie && js == je)
{
if (a[is][js] == k)
return 1;
else
return 0;
}
int im=(is+ie)/2, jm=(js+je)/2;
int result = 0;
//printf("is=%d, im=%d, ie=%d, js=%d, jm=%d, je=%d\n", is, im, ie, js, jm, je);
if (a[im][jm] == k)
return 1;
if (k < a[im][jm])
{
result |= binarySearch(a, is, im-1, js, jm-1, k);
if (result == 1) return 1;
result |= binarySearch(a, is, im-1, jm, je, k);
if (result == 1) return 1;
result |= binarySearch(a, im, ie, js, jm-1, k);
}
if (k > a[im][jm])
{
//printf("%d, %d, %d, %d\n", im+1, ie, jm+1, je);
//printf("%d, %d, %d, %d\n", is, im, jm+1, je);
//printf("%d, %d, %d, %d\n", im+1, ie, js, jm);
result |= binarySearch(a, im+1, ie, jm+1, je, k);
if (result == 1) return 1;
result |= binarySearch(a, is, im, jm+1, je, k);
if (result == 1) return 1;
result |= binarySearch(a, im+1, ie, js, jm, k);
}
return result;
}
int main(void)
{
int m, n, i, j;
int a[N][N];
int k;
while (scanf("%d%d", &m, &n) != EOF)
{
scanf("%d", &k);
for(i=0; i<m; i++)
for(j=0; j<n; j++)
scanf("%d", &a[i][j]);
int result = binarySearch(a, 0, m-1, 0, n-1, k);
if (result == 1)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}
/**************************************************************
Problem: 1384
User: liangrx06
Language: C
Result: Accepted
Time:610 ms
Memory:4744 kb
****************************************************************/
http://ac.jobdu.com/problem.php?pid=1385
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。
抓住前序遍历和中序遍历的特点。
#include <stdio.h>
#include <string.h>
#define N 1000
int getAfter(int *b, int *m, int *a, int len)
{
if (len == 1)
{
if (b[0] != m[0])
return 0;
a[0] = b[0];
return 1;
}
int root = b[0];
int i;
int res;
for (i=0; i<len; i++)
{
if (m[i] == root)
break;
}
if (i == len)
return 0;
a[len-1] = root;
if (i > 0)
{
res = getAfter(b+1, m, a, i);
if (res == 0)
return 0;
}
if (len-1-i > 0)
{
res = getAfter(b+1+i, m+1+i, a+i, len-1-i);
if (res == 0)
return 0;
}
return 1;
}
int main(void)
{
int n, i, res;
int b[1000], m[1000], a[1000];
while (scanf("%d", &n) != EOF)
{
for (i=0; i<n; i++)
scanf("%d", &b[i]);
for (i=0; i<n; i++)
scanf("%d", &m[i]);
res = getAfter(b, m, a, n);
if (res == 0)
printf("No");
else
{
for (i=0; i<n; i++)
printf("%d ", a[i]);
}
printf("\n");
}
return 0;
}
/**************************************************************
Problem: 1385
User: liangrx06
Language: C
Result: Accepted
Time:0 ms
Memory:912 kb
****************************************************************/