第五届河南省大学生程序设计竞赛
四道题用搜索写的(3dfs+1bfs),啊这。
A 奇怪的排序
签到题,按数的倒序排序。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int N=100005;
const int inf=0x3f3f3f3f;
typedef long long ll;
int T,n,m,ans;
struct node{
int x,y;
}s[N];
int cmp(node x,node y){
return x.y<y.y;
}
int main()
{
int i,j,k,x,y;
scanf("%d",&n);
while(n--){
scanf("%d %d",&x,&y);
m=y-x+1;
for(i=0;i<m;i++){
s[i].x=i+x;
int t=i+x,c=0;
do{
c=c*10+t%10;
}while(t/=10);
s[i].y=c;
}
sort(s,s+m,cmp);
for(i=0;i<m;i++){
printf("%d",s[i].x);
if(i!=m-1) printf(" ");
else printf("\n");
}
}
return 0;
}
B 最强DE战斗力
用c写完发现是大数,改Java。我用的是记忆化搜索,如果一个数没有被搜索过,就把它分解成两个数搜索,这两个数最强战斗力的乘积就是这个数的最强的战斗力。前几个数要分别处理一下,赋初值。
这也是找规律的题:看最多能分解多少3,然后计算乘积。
import java.math.BigInteger;
import java.util.Scanner;
public class Main {
static BigInteger[] ab = new BigInteger[1005];
public static void main(String[] args) {
ab[0] = BigInteger.valueOf(1);
ab[1] = BigInteger.valueOf(1);
ab[2] = BigInteger.valueOf(2);
ab[3] = BigInteger.valueOf(3);
Scanner cin = new Scanner(System.in);
int n = cin.nextInt();
for(int i=1;i<=n;i++) {
int x=cin.nextInt();
dfs(x);
System.out.println(ab[x]);
}
}
public static BigInteger dfs(int x) {
if(ab[x]!=null) {
return ab[x];
}
BigInteger big = new BigInteger("0");
for(int i=1;i<=x/2;i++) {
if(ab[i]==null) ab[i] = dfs(i);
if(ab[x-i]==null) ab[x-i] = dfs(x-i);
big = big.max(ab[i].multiply(ab[x-i]));
// System.out.println(x+":"+big);
}
return ab[x]=big;
}
}
C 试 制 品
队友csy大佬写的,每次有新的试制品制成时,就继续制作。要处理字符串,处理起来稍微有点麻烦。
#include<bits/stdc++.h>
using namespace std;
set<string> ss;
set<string> ss2;
int n,m;
string a[9999];
bool signl[9999];
void ts(){
int gg=1;
for(int i=0;i<n;i++){
if(signl[i])continue;
string se = a[i];
string sse="";
int len = se.size();
int j=0,sign=1;
while(se[j-1]!='='){
if(se[j]!='+'&&se[j]!='='){
sse+=se[j];
}else{
if(ss.find(sse)==ss.end()){
// cout<<"out:"<<sse<<endl;
sign=0;
break;
}else{
// cout<<"in:"<<sse<<endl;
sse="";
}
}
j++;
}
// cout<<"------------------"<<endl;
if(sign){
// cout<<"配对成功!"<<endl;
sse="";
for(;j<=len;j++){
if(se[j]!='+'&&j<len){
sse+=se[j];
}else{
// cout<<sse<<endl;
if(ss.find(sse)==ss.end())ss2.insert(sse);
ss.insert(sse);
sse="";
}
}
signl[i]=true;
gg=0;
break;
}
// cout<<"------------------"<<endl;
}
if(gg){
return;
}
ts();
}
int main(){
cin>>n;
for(int i=0;i<n;i++){
cin>>a[i];
}
cin>>m;
string e;
for(int i=0;i<m;i++){
cin>>e;
ss.insert(e);
}
ts();
set<string>::iterator it = ss2.begin();
cout<<ss2.size()<<endl;
for(;it!=ss2.end();it++){
cout<<*it<<endl;
}
return 0;
}
D 遥 控 器
先各种处理,然后bfs写的。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
const int N=1005;
const int inf=0x3f3f3f3f;
typedef long long ll;
int T,n,m,ans,flag;
int a[N],b[N];//数字存a,符号存b
struct node{
int pos,cnt;//数字,步数
}s,t;
int bfs(int x,int y){
int vis[N]={0};
queue<node>q;
s.pos=x;s.cnt=0; vis[x]=1;
q.push(s);
for(int i=0;i<=9;i++){
for(int j=0;j<=9;j++){
if(i==0){//一位数且数字键没坏 存
if(a[j]==1&&vis[j]==0){
vis[j]=1;
s.pos=j;s.cnt=1;
q.push(s);
}
}
else {//两位数字且数字键没坏 存,步数加3
int temp=i*10+j;
if(a[i]&&a[j]&&vis[temp]==0){
vis[temp]=1;
s.pos=temp;s.cnt=3;
q.push(s);
}
}
}
if(b[3]==0) break;//组合键坏了就退出
}
ans-1;
while(!q.empty()){
t=q.front(); q.pop();
if(t.pos==y) return t.cnt;
s.cnt=t.cnt+1;
if(b[1]) {//加
s.pos=t.pos+1;
if(s.pos==100) s.pos=0;
if(vis[s.pos]==0){
vis[s.pos]=1;
q.push(s);
}
}
if(b[2]) {//减
s.pos=t.pos-1;
if(s.pos==-1) s.pos=99;
if(vis[s.pos]==0){
vis[s.pos]=1;
q.push(s);
}
}
}
return -1;
}
int main()
{
int i,j,k,x,y;
scanf("%d",&m);
while(m--){
int t=0;
for(i=1;i<=13;i++){
if(i==4) scanf("%d",&b[1]);
else if(i==8) scanf("%d",&b[2]);
else if(i==12) scanf("%d",&b[3]);
else if(i==13) scanf("%d",&a[0]);
else{
t++;
scanf("%d",&a[t]);
}
}
scanf("%d %d",&x,&y);
printf("%d\n",bfs(x,y));
}
return 0;
}
E 奇妙的图案(待补)
F Metric Matrice
条件判断,读懂题就行,签到题。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int N=105;
const int inf=0x3f3f3f3f;
typedef long long ll;
int T,n,m,ans,s,flag;
int a[N][N];
int main()
{
int i,j,k,x,y;
scanf("%d",&m);
while(m--){
int f[5]={0};
scanf("%d",&n);
for(i=1;i<=n;i++)
for(j=1;j<=n;j++){
scanf("%d",&a[i][j]);
if(i==j) {
if(a[i][j]!=0) f[1]=1;
}
else {
if(a[i][j]<=0) f[2]=1;
}
}
for(i=1;i<=n;i++)
for(j=i+1;j<=n;j++){//左下部分不用判断
if(a[i][j]!=a[j][i]) f[3]=1;
}
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
for(k=1;k<=n;k++){
if(a[i][j]+a[j][k]<a[i][k]) f[4]=1;
}
for(i=1;i<=4;i++){
if(f[i]){
f[0]=1;
printf("%d\n",i);
break;
}
}
if(f[0]==0) printf("0\n");
}
return 0;
}
F Divideing Jewels
dfs搜索+一点小剪枝
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int N=100005;
const int inf=0x3f3f3f3f;
typedef long long ll;
int T,n,m,ans,s,flag;
int a[N];
void dfs(int sum){
if(flag||sum>s) return;
if(sum==s) {
flag=1;
return;
}
for(int i=1;i<=10;i++){
if(a[i]){
a[i]--;
dfs(sum+i);
a[i]++;
}
}
}
int main()
{
int i,j,x,y;
for(int k=1;;k++){
flag=s=0;
for(i=1;i<=10;i++){
scanf("%d",&a[i]);
s+=a[i]*i;
}
if(!s) break;
if(s&1) flag=0;
else {
s/=2;
dfs(0);
}
printf("#%d:",k);
if(flag) printf("Can be divided.\n\n");
else printf("Can't be divided.\n\n");
}
return 0;
}