Playfair密码表
题目链接:
http://hihocoder.com/problemset/problem/1361解题思路:
模拟即可。AC代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 30;
int vis[N];
char output[N];
int main(){
string str;
while(cin>>str){
memset(vis,0,sizeof(vis));
int len = str.size();
for(int i = 0; i < len; ++i){
if(str[i] == 'J')
str[i] = 'I';
}
int l = 0;
for(int i = 0; i < len; ++i){
if(!vis[str[i]-'A'])
output[l++] = str[i];
vis[str[i]-'A'] = 1;
}
for(int i = 0; i < 26; ++i){
if(!vis[i] && i != 9)
output[l++] = 'A'+i;
}
for(int i = 0; i < 25; ++i){
printf("%c",output[i]);
if(i%5 == 4)
puts("");
}
}
return 0;
}
修补木桶(二分)
题目链接:
http://hihocoder.com/problemset/problem/1362解题思路:
二分答案,枚举起点。
AC代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 1005;
int n,m,L;
int a[N];
int solve(int x){
int num = 0;
for(int i = 0; i < n; ++i){
if(a[i] < x){
++num;
i += L-1;
}
}
return num;
}
int main(){
while(~scanf("%d%d%d",&n,&m,&L)){
for(int i = 0; i < n; ++i)
scanf("%d",&a[i]);
int l = 0,r = 1e9+7;
while(l <= r){
int mid = (l+r)/2;
int num = 10000;
for(int i = 0; i < L; ++i){
for(int j = 0; j < n-1; ++j)
swap(a[j],a[j+1]);
num = min(num,solve(mid));
}
if(num <= m) l = mid+1;
else r = mid-1;
}
printf("%d\n",r);
}
return 0;
}
图像算子(高斯消元)
题目链接:
http://hihocoder.com/problemset/problem/1363解题思路:
解线性方程组,高斯消元。
AC代码:
#include<bits/stdc++.h>
#define eps 1e-9
using namespace std;
const int N = 105;
const int M = 10005;
int h,w,d;
int a[N][N];
int b[N][N];
double Mat[M][M];
double V[M];
void Gasse(int n,int m){
int i,j,k = 0;
for(j = 0; j < m; ++j){
for(i = k; i < n; ++i){
if(fabs(Mat[i][j]) > eps)
break;
}
if(i == n)
continue;
for(int p = 0; p < m; ++p)
swap(Mat[i][p],Mat[k][p]);
swap(V[i],V[k]);
double tmp = Mat[k][j] ;
for(int p = j; p < m; ++p)
Mat[k][p] /= tmp;
V[k] /= tmp;
for(int p = 0; p < n; ++p){
if(p!=k && (fabs(Mat[p][j])>eps)){
tmp = Mat[p][j];
for(int q = 0; q < m; ++q)
Mat[p][q] -= tmp*Mat[k][q];
V[p] -= tmp*V[k];
}
}
++k;
}
}
int main(){
while(~scanf("%d%d%d",&h,&w,&d)){
for(int i = 0; i < h; ++i){
for(int j = 0; j < w; ++j){
scanf("%d",&a[i][j]);
}
}
for(int i = 0; i < h-d+1; ++i){
for(int j = 0; j < w-d+1; ++j){
scanf("%d",&b[i][j]);
}
}
int r = 0;
for(int i = 0; i < h-d+1; ++i){
for(int j = 0; j < w-d+1; ++j){
for(int p = 0; p < d; ++p){
for(int q = 0; q < d; ++q){
Mat[r][p*d+q] = a[i+p][j+q];
}
}
V[r] = b[i][j];
r++;
}
}
Gasse(r,d*d);
for(int i = 0; i < d*d; ++i){
if(i%d != 0)
printf(" ");
if(V[i] > -1e-6)\
printf("%.0f",(V[i]+1e-6));
else
printf("%.0f",(V[i]-1e-6));
if(i%d == d-1)
printf("\n");
}
}
return 0;
}
奖券兑换(多重背包)
题目链接:
http://hihocoder.com/problemset/problem/1364解题思路:
二进制优化背包
AC代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 100005;
map<pair<int,int>,int> mp;
int dp[N];
int main(){
int n,m;
while(~scanf("%d%d",&n,&m)){
int need,value;
for(int i = 1; i <= n; ++i) {
scanf("%d%d",&need,&value);
++mp[make_pair(need,value)];
}
vector<pair<pair<int,int>,int> > v(mp.begin(),mp.end());
for(int i = 0; i < (int)v.size(); ++i){
int num = v[i].second;
need = v[i].first.first;
value = v[i].first.second;
for(int k = 1; num > 0; k <<= 1) {
int mul = min(k,num);
for(int j = m; mul * need <= j; --j) {
dp[j] = max(dp[j],dp[j-mul*need] + mul*value);
}
num -= mul;
}
}
int ans = *max_element(dp, dp+m+1);
printf("%d\n", ans);
}
return 0;
}