#include<iostream>
using namespace std;
const int N = 3403;
const int M = 12881;
int dp[M] = {0};
int max(int x, int y)
{
return x > y ? x : y;
}
int main()
{
int n, m;
int w[N], d[M];
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
cin >> w[i] >> d[i];
}
for (int i = 1; i <= n; i++)
{
for (int j = m; j >= w[i]; j--)
{
dp[j] = max(dp[j-w[i]] + d[i], dp[j]);
}
}
cout << dp[m] << endl;
return 0;
}
#include <iostream>
#include <queue>
#include <algorithm>
#include <cstring>
using namespace std;
struct point
{
int x, y, ckl, time;
point (int xx,int yy, int cc, int tt):x(xx), y(yy), ckl(cc), time(tt){};
};
int r,c,t;
int min_time = 1 << 30;
int dx[4] = {0, 0, 1, -1};
int dy[4] = {1, -1, 0, 0};
char mp[210][210];
bool visited[210][210][11];
int bfs(int x, int y, int ex, int ey, int t)
{
queue<point> q;
q.push(point(x, y, t, 0));
while (!q.empty())
{
point temp = q.front();
q.pop();
for (int i = 0; i < 4; i++)
{
int sx = temp.x + dx[i];
int sy = temp.y + dy[i];
if (sx == ex && sy == ey)
{
min_time = temp.time + 1;
return true;
}
if (mp[sx][sy] == '*')
{
if (sx >= 0 && sx < r && sy >= 0 && sy < c && !visited[sx][sy][temp.ckl])
{
visited[sx][sy][temp.ckl] = true;
q.push(point(sx, sy, temp.ckl, temp.time + 1));
}
}
if (mp[sx][sy] == '#')
{
if (sx >= 0 && sx < r && sy >= 0 && sy < c && !visited[sx][sy][temp.ckl - 1] && temp.ckl > 0)
{
visited[sx][sy][temp.ckl - 1] = true;
q.push(point(sx, sy, temp.ckl - 1, temp.time + 1));
}
}
}
}
return false;
}
int main(){
cin >> r >> c >> t;
int x, y, ex, ey;
memset(visited, 0, sizeof(visited));
for (int i = 0; i < r; i++)
{
for (int j = 0; j < c; j++)
{
cin >> mp[i][j];
if(mp[i][j] == '@')
{
x = i;
y = j;
mp[i][j] = '*';
}
if(mp[i][j] == '+')
{
ex = i;
ey = j;
mp[i][j] = '*';
}
}
}
if (bfs(x, y, ex, ey, t))
cout << min_time << endl;
else
cout << "-1" <<endl;
}
22、大盗阿福
cpp复制代码
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
#define N 100005
int t,n,ans;int f[N],a[N];
int main(){
scanf("%d",&t);
while(t--){
scanf("%d",&n);memset(f,0,sizeof(f));ans=0;
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<=n;i++){
f[i]=a[i];
f[i]=max(f[i-2]+a[i],f[i-3]+a[i]);
ans=max(ans,f[i]);
}
printf("%d\n",ans);
}
return 0;
}
23、马走日
cpp复制代码
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int f[21][22],n,m,t;
int x[10]={-2,-2,-1,1,2,2,1,-1},y[10]={-1,1,2,2,1,-1,-2,-2};
int x1,y1,ans;
void dfs(int a,int b)
{
bool p=true;
for (int i=1;i<=n;i++)
{
for (int j=1;j<=m;j++)
if (f[i][j]==0)
{
p=false;
break;
}
if (p==false)
break;
}
if (p==true)
{
ans++;
return ;
}
for (int i=0;i<=7;i++)
{
int l=a+x[i];
int k=b+y[i];
if (f[l][k]==1)
continue;
if (l>0&&l<=n&&k>0&&k<=m)
{
f[l][k]=1;
dfs(l,k);
f[l][k]=0;
}
}
}
int main()
{
scanf("%d",&t);
for (int i=1;i<=t;i++)
{
scanf("%d%d",&n,&m);
scanf("%d%d",&x1,&y1);
x1++;
y1++;
memset(f,0,sizeof(f));
f[x1][y1]=1;
ans=0;
dfs(x1,y1);
cout<<ans<<endl;
}
}
24、鸣人的影分身
cpp复制代码
#include<cstdio>
#include<iostream>
using namespace std;
#define N 12
int t,m,n;int f[N][N]; //f[i][j]表示把i分j个的方案数
int main(){
n=10,m=10;
for(int i=0;i<=10;i++) f[0][i]=1;
for(int i=1;i<=10;i++){
for(int j=1;j<=10;j++){
if(i>=j) f[i][j]=f[i][j-1]+f[i-j][j];
else f[i][j]=f[i][i];
}
}
scanf("%d",&t);
while(t--){
scanf("%d%d",&m,&n);
printf("%d\n",f[m][n]);
}
return 0;
}
25、开餐馆
cpp复制代码
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int T,n,k;
int a[105],v[105],pre[105],f[105];
int main(){
scanf("%d",&T);
for (int t=1;t<=T;++t){
scanf("%d%d",&n,&k);
memset(a,0,sizeof(a));
memset(f,0,sizeof(f));
memset(v,0,sizeof(v));
memset(pre,0,sizeof(pre));
for (int i=1;i<=n;++i)
scanf("%d",&a[i]);
for (int i=1;i<=n;++i)
scanf("%d",&v[i]);
for (int i=2;i<=n;++i)
for (int j=i-1;j>=1;--j)
if (a[i]-a[j]>k){
pre[i]=j; break;
}
f[1]=v[1];
for (int i=2;i<=n;++i)
f[i]=max(f[i-1],f[pre[i]]+v[i]);
printf("%d\n",f[n]);
}
}
26、宠物小精灵之收服
cpp复制代码
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
int l,m,n,minn;
int A[105][2];
int f[1005][505];
int main()
{
scanf("%d %d %d",&m,&l,&n);
for(int i=1;i<=n;i++)
{
scanf("%d %d",&A[i][0],&A[i][1]);
}
for(int i=1;i<=n;i++)
{
for(int j=m;j>=A[i][0];j--)
{
for(int k=l;k>=A[i][1];k--)
{
f[j][k]=max(f[j][k],f[j-A[i][0]][k-A[i][1]]+1);
}
}
}
printf("%d ",f[m][l]);
for(int i=0;i<=l;i++)
{
if(f[m][i]==f[m][l])
{
minn=i;
break;
}
}
printf("%d",l-minn);
}
27、单词序列
cpp复制代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
struct Note
{
string sf;
int nus;
} d[31];
string ks,es;
queue<int> q;
bool b[31],vis;
int length;
int sum=0;
int gs(string x,string y)
{
int sum=0;
for(int i=0;i<length;i++) if(x[i]!=y[i]) sum++;
return sum;
}
int main()
{
cin>>ks>>es;
length=ks.size();
int i=1;
char ch;
d[i].sf=ks;
i=2;
while(cin>>d[i].sf) i++;
d[i].sf=es;
q.push(1);
while(!q.empty())
{
int cur=q.front();
q.pop();
if(d[cur].sf==es)
{
printf("%d\n",d[cur].nus+1);
vis=1;
break;
}
for(int j=1;j<=i;j++)
{
if(gs(d[cur].sf,d[j].sf)==1&&!b[j])
{
d[j].nus=d[cur].nus+1;
q.push(j);
b[j]=1;
}
}
}
if(!vis) printf("0\n");
return 0;
}
28、Sudoku
cpp复制代码
#include <stdio.h>
/* 构造完成标志 */
int sign; //0代表false,1代表true
/* 创建数独矩阵 */
int num[9][9];
/* 函数声明 */
void Input();
void Output();
int Check(int n, int key);//返回0代表false,1代表true
int DFS(int n);
/* 主函数 */
main()
{
int test,i,j;
// freopen("in.txt","r",stdin);
scanf("%d",&test);
while(test--)
{
sign=0;//设初始值为0
Input();//输入
DFS(0);
Output();//输出
}
}
/* 读入数独矩阵 */
void Input()
{
int i,j;
for (i = 0; i < 9; i++)
for (j = 0; j < 9; j++)
scanf("%1d",&num[i][j]);//一个数一个数的读
}
/* 输出数独矩阵 */
void Output()
{
int i,j;
for (i = 0; i < 9; i++)
{
for (j = 0; j < 9; j++)
{
printf("%d",num[i][j]);
}
printf("\n");
}
}
/* 判断key填入n时是否满足条件 */
int Check(int n, int key)
{
/* 判断n所在横列是否合法 */
int i,j;
int x,y;
for (j = 0; j < 9; j++)
{
/* i为n竖坐标 */
i = n / 9;
//如果有相同的数,返回0(不合法)
if (num[i][j] == key) return 0;
}
/* 判断n所在竖列是否合法 */
for (i = 0; i < 9; i++)
{
/* j为n横坐标 */
j = n % 9;
//如果有相同的数,返回0(不合法)
if (num[i][j] == key) return 0;
}
/* x为n所在的小九宫格左顶点竖坐标 */
x = n / 9 / 3 * 3;//如:38/9/3*3=3
/* y为n所在的小九宫格左顶点横坐标 */
y = n % 9 / 3 * 3;//如:38%9/3*3=6
/* 判断n所在的小九宫格是否合法 */
for (i = x; i < x + 3; i++)
{
for (j = y; j < y + 3; j++)
{
if (num[i][j] == key) return 0;
}
}
/* 全部合法,返回正确 */
return 1;
}
/* 深搜构造数独 */
int DFS(int n)
{
/* 所有的都符合,退出递归 */
int i;
if (n > 80)
{
sign = 1;
return 0;
}
/* 当前位不为空时跳过 */
if (num[n/9][n%9] != 0)
{
DFS(n+1);
}
else
{
/* 否则对当前位进行枚举测试 */
for (i = 1; i <= 9; i++)
{
/* 满足条件时填入数字 */
if (Check(n, i) == 1)
{
num[n/9][n%9] = i;
/* 继续搜索 */
DFS(n+1);
/* 返回时如果构造成功,则直接退出 */
if (sign == 1) return 0;
/* 如果构造不成功,还原当前位 */
num[n/9][n%9] = 0;
}
}
}
}
29、画家问题
cpp复制代码
#include <iostream>
using namespace std;
int wallC[16][17] = { 0 },paint[16][17] = { 0 };
//wallC 记录墙的颜色,y为黄色,w为白色,将其转为w 为1,y 为0;
//paint记录需要上色的位置,1表示需要上色,0表示不需要上色
int paintGuess(const int& wSize)
{
for (int i = 1; i < wSize; i++)
for (int j = 1; j <= wSize; j++)
{
paint[i + 1][j] =(wallC[i][j] + paint[i][j] + paint[i - 1][j] + paint[i][j + 1] + paint[i][j -1]) % 2;
}
// 枚举第一行的不同状态组合,再以第一行不同状态组合来确定对应位置是否需要paint;
// 因为相邻的两的位置的paint会相互抵消,所以需要以相邻位置的paint与当前颜色来判断
// 是否需要按下
for (int i = 1; i <= wSize; i++)
{
int n = (paint[wSize][i] + paint[wSize - 1][i] + paint[wSize][i + 1] + paint[wSize][i - 1]) % 2;
if (n != wallC[wSize][i])
{
return 1001;
}
//求paint的最小值,所以返回一个大数,然后比较更新得到最小值
}
//判断最后一行是否都已经变成黄色,如果不是则说明这不是解
int times = 0;
//统计解的paint的次数
for (int i = 1; i <= wSize; i++)
for (int j = 1; j <= wSize; j++)
{
if (paint[i][j] == 1)
times++;
}
return times;
}
int enumerate(const int& wSize)
{
int times = 1001;
int steps = 0, n = 1;
while (paint[1][wSize + 1] < 1) // 据二进制进位规则可知,如果wSize的后一位如果为1的话,则代表wSize位的所有组合都已经进行完成了
{
steps = paintGuess(wSize);
if (steps < times) times =steps; //求出最小值
paint[1][1]++;
n = 1;
while (paint[1][n] > 1) //模拟二进制进位
{
paint[1][n] = 0;
n++;
paint[1][n]++;
}
}
return times;
}
int main(void)
{//freopen("D:\\Users\\GZC\\Desktop\\test.txt","r",stdin);
int cases, wSize, r, c;
char color;
for ( r = 0; r<16; r++)
for (c = 0; c < 17; c++)
{
wallC[r][c] = 0;
paint[r][c] = 0;
} // 为良好习惯,清空上次数据
cin >> wSize;
for (r = 1; r <= wSize; r++)
for (c = 1; c <= wSize; c++)
{
cin >> color;
wallC[r][c] = (color== 'y' ? 0 : 1);
}
int times = enumerate(wSize);
if (times > 1000)
cout << "inf" << endl;
else
cout << times<< endl;
return 0;
}
30、Calling Extraterrestrial Intelligence Again
cpp复制代码
#include<iostream>
#include<math.h>
using namespace std;
int isprime(int n)
{
int i;
for(i=3;i<=sqrt(n*1.0);)
{
if(n%i==0)return 0;
i=i+2;
}
return 1;
}
int main()
{//freopen("D:\\Users\\GZC\\Desktop\\test.txt","r",stdin);
double mat[10001];
int i,j,k;
int n,m;
int flag,temp;
int re,pr;
int max;
double a,b;
int p,q;
mat[0]=2;j=1;//最小的素数
for(i=3;i<40000;)
{
if(isprime(i))//先把素数结果提前求出来
{
mat[j]=i;
j++;
}
i=i+2;//偶数直接排除
}
while(scanf("%d %lf %lf",&m,&a,&b)!=EOF)//使用scanf的速度比cin快很多
{
max=0;
if(!m&&!a&&!b)break;
for(i=0;i<j;i++)
{
for(k=0;k<j;k++)
{
if((mat[i]/mat[k])<(a/b))break;//判断条件不符合,直接退出
if(mat[k]*mat[i]>m)break;
if( (mat[i]/mat[k])<=1 && mat[k]*mat[i]>max )
{
max=mat[k]*mat[i];
p=mat[k];
q=mat[i];
}
}
if(mat[i]*2>m)break;
}
cout<<q<<" "<<p<<endl;
}
return 0;
}