赞
踩
搜索加大数的周赛,结果不是很让人满意啊~我这队长水平一般,只能提供环境希望他们多努力努力了~
把几道不算水的题拿出来解析一下~
一道算搜索的递归题,题目大意是,给三个字符串,问第三个是否是前两个字符串嵌套成的.题目叫拉链~基本就那意思了.
基本思想就是递归对比,有几个要注意的地方:
1. 要从后往前比,
2. 当a[i]==b[j]时要挨个试.
源代码:
- #include <myhead>
- const int N=500;
- char a[N],b[N],c[N];
-
- int dfs(int x,int y,int z) {
- if(z<0) {
- return true;
- }
- if(x>=0&&a[x]==c[z]) {
- if(dfs(x-1,y,z-1))
- return true;
- }
- if(y>=0&&b[y]==c[z]) {
- if(dfs(x,y-1,z-1))
- return true;
- }
- return false;
- }
-
- int main() {
- int t,m=1;
- scanf("%d",&t);
- while(t--) {
- scanf("%s%s%s",a,b,c);
- if(dfs(strlen(a)-1,strlen(b)-1,strlen(c)-1)) {
- printf("Data set %d: yes\n",m);
- } else {
- printf("Data set %d: no\n",m);
- }
- m=m+1;
-
- }
- return 0;
- }
还有一种做法是动态规划:
状态数组为 bool dp[i][j] , 也就是c[i+j]由a的前i个和b的前j个组成.
状态转移方程为:
dp[0][0] = 1;
dp[i][0]=dp[i-1][0]&&a[i-1]==c[i-1]; i>0
dp[0][j]=dp[0][j-1]&&b[j-1]==c[j-1]; j>0
dp[i][j] = (dp[i-1][j]&&a[i]==c[i+j]) || (dp[i][j-1]&&b[j]==c[i+j]); i,j>0
源代码:
- #include <myhead.h>
-
- const int N=210;
-
- int main()
- {
- int t,m=1;
- bool dp[N][N];
- string a,b,c;
- cin>>t;
- while(t--) {
- memset(dp,0,sizeof(dp));
- cin>>a>>b>>c;
- dp[0][0]=1;
- for(size_t i=1;i<=a.size();++i) {
- dp[i][0]=(dp[i-1][0]&&a[i-1]==c[i-1]);
- }
- for(size_t j=1;j<=b.size();++j) {
- dp[0][j]=(dp[0][j-1]&&b[j-1]==c[j-1]);
- }
- for(size_t i=1;i<=a.size();++i) {
- for(size_t j=1;j<=b.size();++j) {
- dp[i][j]=(dp[i-1][j]&&a[i-1]==c[i+j-1]) || (dp[i][j-1]&&b[j-1]==c[i+j-1]);
- }
- }
- if(dp[a.size()][b.size()]) {
- printf("Data set %d: yes\n",m);
- } else {
- printf("Data set %d: no\n",m);
- }
- m=m+1;
- }
- return 0;
- }
http://blog.csdn.net/gj_fb_dabai/article/details/8742470
直接发链接了~
题目大意:
给n个数 ,问这n个数能不能组成一个正方形.
解题思想:
一道普通的回溯法dfs, 状态组为(剩余长度num,已经分了几堆m,总共的剩余长度ssum,当前搜到的位置s);初始状态为 (sum/4,1,sum,0).
直接搜索当然会超时,需要有几点注意.
1.当m==3时即可退出,因为若所有数的合sum%4==0 最后剩余的一组一定满足条件.
2.对数组按从大到小顺序排序,这样只要搜索比当前值大的值即可.
状态转移方程为:
- num<0 -> return false;
- num==0
- -> m==3 -> return true;
- -> ssum%(4-m)==0 -> return (sum/4,m+1,ssum,0);
- else -> return flase;
- num!=0 -> (num-a[i],m,ssum-a[i],i+1);
-
源代码:
- #include <myhead.h>
-
- const int N=30;
- int n,sum;
- bool _hash[N];
- int dis[N];
-
- void init() {
- sum=0;
- memset(_hash,0,sizeof(_hash));
- scanf("%d",&n);
- for(int i=0;i<n;++i) {
- scanf("%d",&dis[i]);
- sum+=dis[i];
- }
- dis[n]=sum;
- sort(dis,dis+n);
- }
-
- bool dfs(int num,int m,int ssum,int s) {
- if(num==0) {
- if(m==3) {
- return true;
- } else {
- return dfs(sum/4,m+1,ssum,0);
- }
- }
- for(int i=s;i<n;++i) {
- if(!_hash[i]) {
- _hash[i]=true;
- if(dfs(num-dis[i],m,ssum-dis[i],i+1)) {
- return true;
- }
- _hash[i]=false;
- }
- }
- return false;
- }
-
- int main()
- {
- int t;
- scanf("%d",&t);
- while(t--) {
- init();
- if(sum%4==0&&dfs(sum/4,1,sum,0)) {
- puts("yes");
- } else {
- puts("no");
- }
- }
- return 0;
- }
直接源代码了:
- #include <myhead.h>
-
- const int N=10010;
-
- int main()
- {
- int t;
- scanf("%d",&t);
- while(t--) {
- int s;
- scanf("%d",&s);
- int a_size,b_size,t;
- int a[N],b[N];
- memset(a,0,sizeof(a));
- memset(b,0,sizeof(b));
- scanf("%d",&a_size);
- for(int i=0;i<a_size;++i) {
- scanf("%d",&t);
- a[t]++;
- }
- scanf("%d",&b_size);
- for(int i=0;i<b_size;++i) {
- scanf("%d",&t);
- b[t]++;
- }
- int sum=0;
- for(int i=1;i<s;++i) {
- sum=sum+(a[i]*b[s-i]);
- }
- printf("%d\n",sum);
- }
- return 0;
- }
-
根据要求 ,<br>换行, <hr>换行输出80个'-', 每80个字符换行一次.
源代码:
- #include <iostream>
- #include <string>
- using namespace std;
-
- int main()
- {
- string szWord;
- int nCount = 0;
- int i;
- while (cin >> szWord)
- {
- if (szWord == "<hr>")
- {
- if (nCount != 0)
- cout << endl;
- for (i=0; i<80; i++)
- cout << "-";
- cout << endl;
- nCount = 0;
- }
- else if (szWord == "<br>")
- {
- cout << endl;
- nCount = 0;
- }
- else
- {
- if (nCount + szWord.size() + (nCount == 0 ? 0 : 1) > 80)
- {
- cout << endl;
- cout << szWord;
- nCount = szWord.size();
- }
- else
- {
- if (nCount != 0)
- cout << " ";
- cout << szWord;
- nCount += szWord.size() + 1;
- }
- }
- }
- cout << endl;
- return 0;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。