TP1 小田的最大价值

思路:输入数组之后,先将他按从小到大排序,排序完之后,将他的极大值和极小值相减,判断是否大于k,如果是,输出极大值,反之输出次大值。 代码:

if(k>(a[n]-a[1])) 
	{
		cout<<a[n-1];
		return 0;
	}
	else cout<<a[n];

样例: 5 6 1 2 3 4 5 5-1=4,4不大于6,输出次大值,4。 错误点:没看到数据范围,数组开小了。

TP2 小田的交换数字

思路: 关键点: 同余定理: (a+b)%x==(a%x+b%x)%x (a×b)%x==(a%x×b%x)%x 当两个数和一定时: a和b相差越大乘积越小, 相差越小乘积越大。 通过上面的两个关键点,我们可以知道,要想让乘积越小只要让a和b相差最大就行了。想让乘积不超,就用同余定理的第二条就行了。 代码:

for(int i=0;i<n;i++)
	{
		if(b[i]>a[i])
			swap(a[i],b[i]);
	}
	for(int i=0;i<n;i++)
	{
		num=(num*10+a[i]-'0')%mod;
		ans=(ans*10+b[i]-'0')%mod;
	}
	cout<<(num%mod*ans%mod)%mod;

样例: 3 159 586 交换第三位,结果为 156×589=91884。

TP3小田的气球真好看

思路:循环枚举i,通过i来找最后一个满足条件的j,找到之后res+=j-i+1,最后输出res。 代码:

for(int i=1,j=0;i<=n;i++)
	{
		while(j+1<=n&&(j+1-v[a[j+1]]<=k||v[a[j+1]]==0))
		{
			j++;
			v[a[j]]=j;
		}
		res+=j-i+1;
		if(v[a[i]]==i) v[a[i]]=0;
	}

样例: 4 1 1 0 0 1 完美区间一共有: [1],[0],[0],[1],[1,0],[0,0],[0,1],[1,0,0], [1,0,0,1] 不是完美区间,因为两个1之间的距离大于 k。

TP4表达式求值

思路:在一个表达式之中只会有5种表达式:

  • 't',运算结果为 true

  • 'f',运算结果为 false

  • '!(表达式)',运算过程为对内部表达式 进行 ​逻辑非​(NOT)运算

  • '&(表达式s1, 表达式s2, ..., 表达式sn)',运算过程为对 2 个或以上内部表达式 s1, s2, ..., sn进行 ​逻辑与​(AND)运算

  • '|(表达式s1, 表达式s2, ..., 表达式sn)',运算过程为对 2 个或以上内部表达式 s1, s2, ..., sn 进行 ​逻辑或​(OR)运算 所以我们直接分类讨论,因为有一点难讲,直接看代码。 代码:

    for(int i=0;i<s.size();i++)
      	{
      		if(s[i]==','||s[i]=='(') 进入下一层。
      		else if(s[i]==')')
      		{
      			int ling=0,yi=0;
      			循环
      			{
                                  计数。
      			 }
      			if(a.top()=='!')
      			{
      				进行逻辑非运算。
      			}
      			else if(a.top()=='&')
      			{
                    进行逻辑与运算。
      			}
      			else 
      			{
      				进行逻辑或运算。
      			}
      		}
      		else a.push(s[i]);
      	}
      	if(a.top()='f') cout<<"false\n";
      	else cout<<"true\n";
      }
    

    样例: 2 &(|(f,f),f) !(!(t)) 点1: &(f,f) false 点2: !(f) true

    TP5小W去冒险

思路:枚举i和j,如果i和j满足条件,就把cnt++,还有把所有和i,j相连的点标记为已看,最后输出cnt。 代码:

void dfs(int i,int j)
{
	if(i+1<=n&&a[i+1][j]>0)
	{
		a[i+1][j]=0;
		dfs(i+1,j);
	}
	if(i-1>=1&&a[i-1][j]>0)
	{
		a[i-1][j]=0;
		dfs(i-1,j);
	}
	if(j+1<=m&&a[i][j+1]>0)
	{
		a[i][j+1]=0;
		dfs(i,j+1); 
	}
	if(j-1>=1&&a[i][j-1]>0)
	{
		a[i][j-1]=0;
		dfs(i,j-1);
	}
}
for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			if(a[i][j]>0)
			{
				cnt++;
				dfs(i,j);
			}

TP6 检查总结

思路:dp[i]表示需要几步才能把i到n的这些数字变成合法。 对于dp[i], 删:dp[i+1]+1 不删:dp[i+a[i]+1] 所以dp[i]=min(dp[i+1]+1,dp[i+a[i]+1]; 代码:

dp[n]=1;
	for(int i=n-1;i>=1;i--)
	{
		if(i+a[i]>n) dp[i]=dp[i+1]+1;
		else dp[i]=min(dp[i+1]+1,dp[i+a[i]+1]);
	}