目录
C 六学家的困惑(模拟+思维)
E 数独挑战(dfs)
H Parco_Love_GCD(思维)
I 炒股(思维)
L 石头剪刀布(水题)
【题意】
有两个字符串,每次可以从两个字符串的两端取一个数字,需要最终组成的字符串数字最大。
【解题思路】
如果给的是一个字符串会不会简单一点呢...?答案是肯定的,直接从两端找就可以啦,如果两端的数一样,那么继续往里找,从里面的数比较大的一端先取,然后就得到了一个字符串能够组成的最大字符串,同理另一个字符串也先做这样的处理。最后把他们组合起来再做一次处理。但是这里需要注意,第二个字符串要倒序和第一个字符串组合,这个应该很容易理解。
【代码】
#include
using namespace std;
string s1,s2;
string f1(string s)
{
string p;
int l=0,r=s.size()-1;
while(l<=r)
{
if(s[l]>s[r])p=p+s[l++];
else if(s[l]s[tr])
{
f=1;
p=p+s[l++];
break;
}
else if(s[tl]>s1>>s2;
string ts1,ts2,ss;
ts1=f1(s1);
ts2=f1(s2);
ss=ts1;
for(int i=ts2.size()-1;i>=0;i--)
ss=ss+ts2[i];
string ans=f1(ss);
printf("Case #%d: ",kase++);
cout<
【题意】9*9的数独游戏。往空格内填1-9的数字,要求每9个格子,每一列每一行不能出现重复数字。
【解题思路】很经典的一道dfs题...然而我敲了很久 coding能力真的不行
用row[i][x]标记第i出现了第x个数,同理col标记列,t标记方格。然后dfs暴搜即可,如果y=8时,记得要搜下一行~
【代码】
#include
using namespace std;
int flag=0;
int a[15][15],vis[15],col[15][15],row[15][15],t[15][15][15];
void dfs(int x,int y)
{
if(flag)return;
if(x==9)
{
flag=1;
for(int i=0;i<9;i++)
{
printf("%d",a[i][0]);
for(int j=1;j<9;j++)
printf(" %d",a[i][j]);
printf("\n");
}
return;
}
if(!a[x][y])
{
for(int i=1;i<=9;i++)
{
if(!row[x][i] && !col[y][i] && !t[x/3][y/3][i])
{
a[x][y]=i;
row[x][i]=col[y][i]=t[x/3][y/3][i]=1;
if(y==8)dfs(x+1,0);
else dfs(x,y+1);
a[x][y]=0;
row[x][i]=col[y][i]=t[x/3][y/3][i]=0;
}
}
}
else
{
if(y==8)dfs(x+1,0);
else dfs(x,y+1);
}
}
int main()
{
for(int i=0;i<9;i++)
{
for(int j=0;j<9;j++)
{
scanf("%d",&a[i][j]);
if(a[i][j])
{
int x=a[i][j];
row[i][x]=col[j][x]=t[i/3][j/3][x]=1;
}
}
}
dfs(0,0);
}
/*
5 3 0 0 7 0 0 0 0
6 0 0 1 9 5 0 0 0
0 9 8 0 0 0 0 6 0
8 0 0 0 6 0 0 0 3
4 0 0 8 0 3 0 0 1
7 0 0 0 2 0 0 0 6
0 6 0 0 0 0 2 8 0
0 0 0 4 1 9 0 0 5
0 0 0 0 8 0 0 7 9
*/
【题意】
【解题思路】
时限3s…其实很暴力,稍微优化一下即可。根据gcd的性质,数越多gcd肯定越小,所以当一个一个遍历下去的时候,如果gcd已经和整个数组的gcd一样的话,就没必要再往下做了,直接计算后退出即可。但是如果没有这个优化是过不了的。
【代码】
#include
using namespace std;
typedef long long LL;
const int maxn=5e5+5;
const LL mod=1e9+7;
LL a[maxn];
vectorv[maxn];
LL gcd(LL a,LL b)
{
while(b)
{
LL x=a%b;
a=b;
b=x;
}
return a;
}
int main()
{
int n;
LL c=0,ans=0;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
for(int i=1;i<=n;i++)
c=gcd(c,a[i]);
for(int i=1;i<=n;i++)
{
LL x=0;
for(int j=i;j<=n;j++)
{
x=gcd(x,a[j]);
if(x==c)
{
ans=(ans+x*(n-j+1))%mod;
break;
}
else ans=(ans+x)%mod;
}
}
printf("%lld\n",ans);
}
【题意】
胡老师每天能够卖出或买入股票,并且每天只能持有1支股票,给出n天股票的价钱,问在n天之后他最多能靠炒股赚多少钱。
【解题思路】
写写样例然后模拟模拟就可以发现,问题可以转化为数组中有的上升的子序列两端点的差值之和。比如8 7 3 6 9 2 5就等于9-3+5-2=9.
【代码】
#include
using namespace std;
const int maxn=5e5+5;
typedef long long LL;
LL a[maxn];
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i=a[i])
{
ans+=a[i-1]-now;
now=a[i];
}
}
if(a[n-1]>a[n-2])ans+=a[n-1]-now;
printf("%lld\n",ans);
}
【代码】
水题就不解释了...
#include
using namespace std;
int main()
{
int n;
scanf("%d",&n);
while(n--)
{
string str;
cin>>str;
if(str=="Scissors")puts("Rock");
else if(str=="Rock")puts("Paper");
else puts("Scissors");
}
}