暴力for过去。
02 Polygon
计算几何模板。
因为盒子能使用多次,排序后取一个最接近的。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
int a[100010];
int b[100010];
int min3(int a,int b,int c){
if(a<b){
if(a<c)return a;
return c;
}else{
if(b<c)return b;
return c;
}
}
int main(){
int n,m;
while(cin>>n>>m){
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
for(int i=1;i<=m;i++){
scanf("%d",&b[i]);
}
sort(a+1,a+n+1);
sort(b+1,b+m+1);
b[0]=-1e9; b[m+1]=1e9; b[m+2]=1e9;
int pos = 1;
int ans = 0;
for(int i=1;i<=n;i++){
while(b[pos]<a[i] && pos<=m){
pos++;
}
ans+=min3(abs(a[i]-b[pos-1]),abs(a[i]-b[pos]),abs(a[i]-b[pos+1]));
}
cout<<ans<<endl;
}
return 0;
}
04 Happy Value
最大生成树,拿MST改改就好。
贪心。二进制表示下,取n为0的位,填上k。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
char names[111][22];
int main(){
int t;
cin>>t;
while(t--){
ll n,k;
cin>>n>>k;
ll ans = 0;
ll tmp = 1;
while(k){
while(n&tmp){
tmp<<=1;
}
if(k&1)ans|=tmp;
tmp<<=1;
k>>=1;
}
cout<<ans<<endl;
}
return 0;
}
06 01 Matrix
统计两个方向的前缀和(左,上),然后小到大推出来。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
char mat[1010][1010];
int L[1010][1010];
int U[1010][1010];
int MAX[1010][1010];
int cnt[1010];
int ans[1010];
int main(){
int t;
cin>>t;
while(t--){
memset(cnt,0,sizeof(cnt));
memset(ans,0,sizeof(ans));
int n;
int m;
cin>>n>>m;
for(int i=0;i<n;i++){
scanf("%s",mat[i]);
for(int j=0;j<n;j++){
mat[i][j]-='0';
}
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(mat[i][j]){
L[i][j]=1;
U[i][j]=1;
MAX[i][j]=1;
if(i>0){
U[i][j]=U[i-1][j]+1;
}
if(j>0){
L[i][j]=L[i][j-1]+1;
}
if(i>0&&j>0){
int tmp=min(L[i][j],U[i][j]);
MAX[i][j]=min(tmp,MAX[i-1][j-1]+1);
}
}else{
L[i][j]=0;
U[i][j]=0;
MAX[i][j]=0;
}
}
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(MAX[i][j])cnt[MAX[i][j]]++;
}
}
for(int i=n;i>0;i--){
cnt[i]+=cnt[i+1];
}
for(int i=1;i<=m;i++){
int q;
scanf("%d",&q);
printf("%d\n",cnt[q]);
}
}
return 0;
}
07 Pick Game
看完题想都没想写了个miniMax+alapha-beta pruning,结果无限T,都是PKU游戏大赛害的。其实这个题是可以用dp做的。需要把状态编码一下,也就是哪些格子被拿了哪些没有,然后就是状态的范围太大要哈希。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int INF = 1e9;
int v[9][9];
int n,m;
int tot;
int enCode(){
int p=1;
int res=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(v[i][j]){
res|=p;
}
p<<=1;
}
}
return res;
}
bool canPick(int nn,int mm){
int cnt=0;
if(!v[nn-1][mm])cnt++;
if(!v[nn][mm-1])cnt++;
if(!v[nn+1][mm])cnt++;
if(!v[nn][mm+1])cnt++;
return cnt>=2;
}
const int mod = 1000007;
int head[mod+1];
int pre[mod*4];
int dp[mod*4];
int val[mod*4];
int cnt=0;
int find(int x){
int xx=x%mod;
for(int i=head[xx];~i;i=pre[i]){
if(val[i]==x)return dp[i];
}
return -1;
}
void insert(int x,int data){
int xx=x%mod;
pre[cnt]=head[xx];
head[xx]=cnt;
val[cnt]=x;
dp[cnt]=data;
cnt++;
}
int ab(int dep){
if(dep>tot)return 0;
int code = enCode();
if(find(code)!=-1){
return find(code);
}
int res;
if(dep&1){
res=-INF;
}else{
res=INF;
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(v[i][j] && canPick(i,j)){
//make
int tmp=v[i][j];
v[i][j]=0;
//
if(dep&1){ //me
res = max(res, ab(dep+1) + tmp);
}else{ //op
res = min(res, ab(dep+1) - tmp);
}
//unmake
v[i][j]=tmp;
}
//
}
}
insert(code,res);
return res;
}
int main(){
int t;
cin>>t;
while(t--){
memset(v,0,sizeof(v));
memset(dp,0,sizeof(dp));
memset(head,-1,sizeof(head));
cnt=0;
cin>>n>>m;
tot=n*m;
int sum = 0;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>v[i][j];
sum+=v[i][j];
}
}
int ans = ab(1);
cout<<(sum-ans)/2+ans<<endl;
}
return 0;
}
08 Study Words
模拟。恰当利用STL。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const string os="<oldwords>";
const string ot="</oldwords>";
const string as="<article>";
const string at="</article>";
map<string,int> mp;
set<string> dic;
void fun(string tmp){
string realStr="";
int len = tmp.size();
for(int i=0;i<len;i++){
if(tmp[i]>='A' && tmp[i]<='Z'){
tmp[i]+=32;
}
if(tmp[i]>='a' && tmp[i]<='z'){
realStr+=tmp[i];
}else{
if(realStr.size() && !dic.count(realStr)){
mp[realStr]++;
}realStr="";
}
}
if(realStr.size() && !dic.count(realStr)){
mp[realStr]++;
realStr="";
}
}
set<pair<int,string> > ans;
int main(){
int t;
cin>>t;
while(t--){
dic.clear();
mp.clear();
string tmp;
while(cin>>tmp){
if(tmp==os)continue;
if(tmp==ot)break;
for(int i=0;i<tmp.size();i++){
if(tmp[i]>='A' && tmp[i]<='Z'){
tmp[i]+=32;
}
}
dic.insert(tmp);
}
while(cin>>tmp){
if(tmp==as)continue;
if(tmp==at)break;
fun(tmp);
}
ans.clear();
map<string,int>::iterator it;
for(it=mp.begin();it!=mp.end();it++){
ans.insert(make_pair(-it->second,it->first));
}
int cnt = 10;
set<pair<int,string> >::iterator it2;
for(it2=ans.begin();it2!=ans.end();it2++){
cnt--;
cout<< (*it2).second<<endl;
if(!cnt)break;
}
cout<<endl;
}
return 0;
}
模拟。
总的来说,题目都是入门级的,只有07有点难。