实在没有脑细胞做新题,就整理整理旧题吧
nyoj 132:点击打开链
找最长回文子串,但是要求忽略空格和标点,然后将最大回文子串输出.
#include<stdio.h>
#include<string.h>
#include<ctype.h>
char buf[5005], res[5005], pri[5005]; //buf输入,res记录buf中字母并转换成大写,pri记录res中字母在buf中位置
int main()
{
int N;
scanf("%d", &N);
getchar();
while(N--)
{
int m = 0, len, max = 0;
int i, j, x, y;
gets(buf);
len = strlen(buf);
for(i = 0; i < len; i ++)
{
if(isalpha(buf[i])) //判断是否是字母
{
pri[m] = i;
res[m++] = toupper(buf[i]); //字母转换为大写
}
}
for(i = 0; i < m; i ++) //枚举回文串的中间位置i,注意i是中心
{
for(j = 0; i - j >= 0 && i + j < m; j ++) //最长回文字串为奇数
{//枚举回文串的长度
if(res[i - j] != res[i + j])
break; //向两边扩展,不相等跳出
if(j * 2 + 1 > max)
{
max = j * 2 + 1; //记录最长回文字串长度
x = pri[i - j]; //记录最长回文字串起点
y = pri[i + j]; //记录最长回文字串终点
}
}
for(j = 0; i - j >= 0 && i + j < m; j ++) //最长回文字串为偶数
{
if(res[i - j] != res[i + j + 1])
break;
if(j * 2 + 2 > max)
{
max = j * 2 + 2;
x = pri[i - j];
y = pri[i + j + 1];
}
}
}
for(i = x; i <= y; i ++) //x,y为起点,终点
printf("%c", buf[i]);
printf("\n");
}
return 0;
}
nyoj744 : 点击打开链接
找规律.....都说是水题.....其实规律我没找到......
右边界的二进制位数为c,那么2的c次方减1就是最终答案......
#include<stdio.h>
#include <math.h>
int main()
{
long long a, b;
while(scanf("%lld %lld", &a, &b) != EOF)
{
int c = 0;
b ^= a;
while(b)
{
c ++;
b >>= 1;
}
long long ans = 1;
while(c)
{
ans *= 2;
c --;
}
printf("%lld\n", ans - 1);
}
}
tyvj 1001 : 点击打开链接
做这个题想写的就是,看到有关素数的题不要一上来就写素数拆选法,这题就根本用不到.....
#include <stdio.h>
#include <algorithm>
#define N 1000000
using namespace std;
int a[10010];
//bool prime[N];
//int p[1000000], k = 0;
/*
void isprime()
{
int i, j;
prime[0] = prime[1] = 1;
for(i = 2; i < N; i++)
{
if(!prime[i])
{
p[k ++] = i;
for(j = 0; j < k && i * p[j] < N; j ++)
{
prime[i * p[j]] = 1;
if((i % p[j]) == 0)
break;
}
}
}
}
*/
int isprime(int x)
{
if(x <= 1)
return 0;
int i;
for(i = 2; i * i <= x; i++)
{
if(x % i == 0)
return 0;
}
return 1;
}
int main(void)
{
int n, k;
//isprime();
while(scanf("%d %d", &n, &k) != EOF)
{
int i;
for(i = 0; i < n; i++)
scanf("%d", &a[i]);
sort(a, a + n);
int x = a[n - k] - a[k - 1];
if(!isprime(x))
printf("NO\n");
else
printf("YES\n");
printf("%d\n", x);
}
return 0;
}
tyvj1141: 点击打开链接
挺繁琐的一个模拟题, 注意cmp函数
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
struct node
{
char s[30];
};
node str[110];
int let[26];
int cmp(const void *a, const void *b)
{
return (((node *)a)->s[0] > ((node *)b)->s[0] ? 1 : -1);
}
int main (void)
{
int n = 0, i, j;
while(1)
{
gets(&str[n].s[1]);
if(str[n].s[1] == '-' && str[n].s[2] == '1')
break;
int temp = 0, i = 1;
while(isdigit(str[n].s[i]))
{
temp = temp * 10 + (str[n].s[i] - 48);
i ++;
}
str[n].s[0] = temp + 48;
n ++;
}
int c = 0;
qsort(str, n, sizeof(str[0]), cmp);
char sta = str[0].s[0];
while(1)
{
for(i = 0; i < n; i++)
if(str[i].s[0] == sta)
break;
c ++;
j = 0;
while(str[i].s[j] != ' ')
j ++;
j++;
if(str[i].s[j] == 'I' && str[i].s[j + 1] == 'F')
{//处理if语句
j += 3;
char temp = str[i].s[j];
int temp2 = 0;
j += 2;
while(isdigit(str[i].s[j]))
{
temp2 = temp2 * 10 + (str[i].s[j] - 48);
j ++;
}
if(let[temp - 'A'] == temp2)
{
j += 4;
temp2 = 0;
while(isdigit(str[i].s[j]))
{
temp2 = temp2 * 10 + (str[i].s[j] - 48);
j++;
}
sta = temp2 + 48;
continue;
}
else
{
sta = str[i + 1].s[0];
continue;
}
}
if(str[i].s[j] == 'E' && str[i].s[j + 1] == 'N' && str[i].s[j + 2] == 'D')
break;
if(str[i].s[j + 1] == '+')
{//处理赋值语句
char temp = str[i].s[j];
int temp2 = 0;
j += 2;
while(isdigit(str[i].s[j]))
{
temp2 = temp2 * 10 + (str[i].s[j] - 48);
j ++;
}
let[temp - 'A'] += temp2;
sta = str[i + 1].s[0];
continue;
}
if(str[i].s[j + 1] == '?')
{//处理输出语句
sta = str[i + 1].s[0];
continue;
}
if(str[i].s[j] == 'G' && str[i].s[j + 1] == 'O')
{//处理跳转语句
j += 3;
int temp = 0;
while(isdigit(str[i].s[j]))
{
temp = temp * 10 + (str[i].s[j] - 48);
j ++;
}
sta = temp + 48;
continue;
}
}
printf("%d\n", c);
return 0;
}
搜索题,感觉快连搜索题都不会写了.......好慌啊
#include <stdio.h>
int count, n;
int a[40];
int f(int k)
{
int i, j, l;
for(i = 1; i <= (k + 1) / 3; i++)
{
int f = 1;
for(l = 0; l < i; l ++)
{
if(a[k - l] != a[k - i - l] || a[k - i - l] != a[k - i - i - l])
{//三个不相等
f = 0;//不存在长度为i的连续子串
break;
}
}
if(f)//存在长度为i的连续的子串
return 0;
}
return 1;
}
void dfs(int x)
{
if(x == n)
{
count++;
return ;
}
a[x] = 0;
if(f(x))
dfs(x + 1);
a[x] = 1;
if(f(x))
dfs(x + 1);
}
int main (void)
{
while(scanf("%d", &n) != EOF)
{
count = 0;
dfs(0);
printf("%d\n", count);
}
return 0;
}
tyvj 1067: 点击打开链接
动归.其实就是最长递增子序列,两个数组,dp1[i]存放以第i个元素为结尾的最长递增子序列,dp2[i]存放以第i个元素为开头的最长递减子序列,然后每个位置对应这相加,取最大的就好.
#include <stdio.h>
int a[110];
int dp1[110], dp2[110];
int main (void)
{
int n;
while(scanf("%d", &n) != EOF)
{
int i, j;
for(i = 0; i < n; i++)
scanf("%d", &a[i]);
for(i = 0; i < n; i++)
dp1[i] = dp2[i] = 1;
for(i = 0; i < n; i++)
{
for(j = i - 1; j >= 0; j--)
{
if(a[j] < a[i])
dp1[i] = dp1[i] > (dp1[j] + 1) ? dp1[i] : (dp1[j] + 1);
}
}
for(i = n - 1; i >= 0; i--)
{
for(j = i + 1; j <= n; j++)
{
if(a[j] < a[i])
dp2[i] = dp2[i] > (dp2[j] + 1) ? dp2[i] : (dp2[j] + 1);
}
}
int max = -1;
for(i = 0; i < n; i++)
{
if(dp1[i] + dp2[i] - 1 > max)
max = dp1[i] + dp2[i] - 1;
}
printf("%d\n", n - max);
}
return 0;
}
tyvj 1015:点击打开链接
完全背包求最小值,注意初始化。
#include <stdio.h>
int a[11];
int dp[110];
void init()
{
int i;
for(i = 0; i < 110; i++)
dp[i] = 0x3f3f3f3f;
}
int main (void)
{
int i, n, j;
init();
dp[0] = 0;
for(i = 1; i <= 10; i++)
scanf("%d", &a[i]);
scanf("%d", &n);
for(i = 1; i <= 10; i++)
for(j = i; j <= n; j++)
dp[j] = dp[j] < (dp[j - i] + a[i]) ? dp[j] : (dp[j - i] + a[i]);
printf("%d\n", dp[n]);
return 0;
}