ACM集训日记-8月1日
来源:互联网 发布:mac如何双开战网 编辑:程序博客网 时间:2024/09/21 06:15
今天早上a了两道题,第一道题点击打开链接,第二道题点击打开链接,没有题解的帮助,就像是在深山老林里开荒一样,第四题棋盘问题一开始题目理解错了,题目描述是“在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。”一开始我理解成只要棋子不相邻即可,简直大错特错。
void dfs(int z)//这里的z就直接可以代表从第z行开始遍历,一行只放一个,判断是否同行就可以直接解决
{
if(sum==k)//如果棋子数用了k个说明用完了,遍历结束
{
cnt++;
return;
}
else
{
if(z>=n)return;
else
{
for(int i=0;i<n;i++)//确定一行后,在从0到n-1列遍历,判断是否同列也可以直接解决
{
if(judge(z,i))
{
vis[i]=1;
sum++;
dfs(z+1);
sum--;
vis[i]=0;
}
}
dfs(z+1);//然后遍历z+1个棋子的情况
}
}
}
这道题我一开始做出来怎么结果都是1,后来发现在vis[i]=0;后面加了return!我真傻真的,这样sum++后就结束了sum一直都是1,简直傻的可以。
第二道题我用的是强硬的办法,输进去一个数,一直算只包含1和0的数直到可以整除这个数就break出来,简直不要太暴力。就是还没看别人是怎么做的,晚上回去看看别人的题解吧。
下午参加了暑假的第一次训练赛,虽然以前也参加过类似的,是codeforces上的比赛,最终结果是只做出了第一题,第二题胎死腹中,我们最好的是做出了两题,都是英文题目,读题难免有些障碍,第一题点击打开链接,还算好,不过我自己的问题,考虑不是很清楚第一次,用的有点呆呆的方法
#include<iostream>#include<cstdio>using namespace std;int main(){ int cw[7]={118,60,94,62,118,60,94};//为了后面的加法不会越界 int ccw[7]={118,62,94,60,118,62,94}; char a,b,c; int t,i,f1=0,f2=0; cin>>a; c=getchar(); cin>>b; cin>>t; i=t%4; for(int k=0;k<4;k++) { if(cw[k]==int(a)) { if(cw[k+i]==int(b)){f1=1;break;} } } for(int k=0;k<4;k++) { if(ccw[k]==int(a)) { if(ccw[k+i]==int(b)){f2=1;break;} } } if(f1==f2)cout<<"undefined"; else if(f1)cout<<"cw"; else if(f2)cout<<"ccw"; return 0;}
最后判断顺时针还是逆时针的时候我忘记了转4次会回到原点从而无法判断的情况。
第二道题点击打开链接,我就是被第二题磨死的,其实应该也不难,但是我就是一直在后面的某组数据超时了,因为我对每个字母都进行了搜索,超时好像也是没有办法的,这是我的代码:
#include<iostream>#include<vector>#include<cstdio>#include<string.h>#include <algorithm>using namespace std;int asc[135][2];int asc2[135];int main(){ int a,b,cnt=0,min,max; char c; char l[1000005]; cin>>a>>b; for(int i=1;i<=a;i++) { //cin>>c; scanf("%d",&c); l[i]=c; } memset(asc,0,sizeof(asc)); memset(asc2,0,sizeof(asc2)); for(int i=1;i<=a;i++) { for(int j=1;j<i;j++) { if(l[j]!=l[i])asc[int(l[i])][0]=i; else {asc[int(l[i])][0]=j;break;} } for(int k=a;k>i;k--) { if(l[k]!=l[i])asc[int(l[i])][1]=i; else {asc[int(l[i])][1]=k;break;} } } min=9999999; max=0; for(int i=65;i<=90;i++)//后面较大的数据,在这里就会超时! { for(int j=i+1;j<=90;j++) { if(asc[j][0]!=0&&asc[i][0]!=0) { if(asc[i][0]<asc[j][0]/*&&asc[i][0]<min*/)min=asc[j][0]/*min=asc[i][0]*/; else if(asc[j][0]<min)min=asc[i][0]; if(asc[i][1]<asc[j][1]&&asc[j][1]>max)max=asc[j][1]; else if(asc[i][1]>max)max=asc[i][1]; } } } //cout<<min<<max; for(int i=min;i<=max;i++) { asc2[l[i]]++; } for(int i=65;i<=90;i++) { if(asc2[i]!=0)cnt++; } //cout<<cnt; if(cnt>b)cout<<"YES"; else cout<<"NO"; return 0;}
这道题我上网看了昨天前辈们做的题解,感觉很精妙,下面是转载的加上我自己的理解(如果分析有误,请提出一并探讨!)
- while(~scanf("%d%d%s",&n,&k,s)){
- cnt=0;
- for(i=0;i<26;i++) a[i]=b[i]=0;
- for(i=0;s[i];i++) a[s[i]-'A']++; //用数组a来标记在某个字母门进入的游客是否已经走完
- for(i=0;s[i];i++){ //用数组b来标记每个字母门需要用到守卫的个数
- if(!b[s[i]-'A']){
- cnt++;
- b[s[i]-'A']=1;
- }
- if(cnt>k){
- puts("YES"); //如果需要的守卫大于已经有的守卫,那么说明需要增添守卫,然后跳出循环即可
- break;
- }
- a[s[i]-'A']--;
- if(!a[s[i]-'A']){ //如果一个门应该进去的游客已经走完那么正在执勤的守卫-1
- cnt--;
- }
- }
- if(i==n) puts("NO");
- ACM集训日记-8月1日
- ACM集训日记-8月8日
- ACM集训日记-8月2日
- ACM集训日记-8月3日
- ACM集训日记-8月4日
- ACM集训日记-8月5日
- ACM集训日记-8月7日
- ACM集训日记-8月9日
- ACM集训日记-8月10日
- ACM集训日记-8月11日
- ACM集训日记-8月12日
- ACM集训日记-8月14日
- ACM集训日记-8月15日
- ACM集训日记-8月16日
- ACM集训日记-8月17日
- ACM集训日记-8月18日
- ACM集训日记-8月19日
- ACM集训日记-8月21日
- java接口interface
- 如何新建一个maven项目?
- Android布局优化之ViewStub、include、merge使用与源码分析
- null
- 2017/8/1训练日记(16cf1题解分析)
- ACM集训日记-8月1日
- 变量提升
- SnackDown 2017 Online Elimination Round #Prefix Xor -- 主席树
- leetcode 169. Majority Element | 摩尔投票法
- 趣味编程:静夜思(Swift版)
- [USACO3.3.4]Home on the Range
- [kuangbin带你飞]专题二 搜索进阶 E
- linux 下oracle导入dmp文件
- 查询数据表中某字段值是否有多条记录相同的sql语句