18257 一起来填数吧
题意:水题,没什么好说的,就按照题意输出,注意一下输出格式,不要输出行末空格就行
#include <iostream>
#include <cstring>
#define ll long long
using namespace std;
const int N = 55 + 5;
int a[N][N];
int main()
{
#ifdef local
freopen("in.txt","r",stdin);
#endif // local
int T; cin >> T;
while(T--)
{
int n,m; cin >> n >> m;
int number = 0;
for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++)
{
if(i & 1)
a[j][i] = ++number;
else
a[n-j+1][i] = ++number;
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
cout << a[i][j];
if(j != m)
cout << " ";
}
cout << endl;
}
cout << endl;
}
return 0;
}
18255 体育课
题意:问一个数组能否在去掉之多一个数诸侯使得数组有序。
有序可以分为递增跟递减两种,其实都一样,你只要判断一种,比如你判断递增,然后倒置一些数组再判断一次(其实就是判断原数组的递减情况),关于如何判断:
以递增为例,可以用一个pre[i]表示数组中以第i个数结尾的连续递增个数,用suff[i]表示以第i个数为开头的递增个数,这两个都这样扫一遍数组就可以得到。然后判断的时候根据a[i-1],a[i+1]的值,以及pre[i-1],suff[i+1]的值,就可以很快判断出移除第i个数能否使得原数组有序。时间复杂度O(n),每次记得清空pre以及suff数组。
#include <iostream>
#include <cstring>
#define ll long long
using namespace std;
const int N = 1000 + 5;
const int INF = 10000;
int pre[N],suff[N];
int a[N],n;
bool check(int cond)
{
memset(pre,0,sizeof(pre));
memset(suff,0,sizeof(suff));
if(cond)
for(int i=1;i<=n/2;i++)
swap(a[i],a[n-i+1]);
for(int i=1; i<=n; i++)
{
if(a[i] >= a[i-1])
pre[i] = pre[i-1] + 1;
else
pre[i] = 1;
}
for(int i=n;i>=1;i--)
{
if(a[i] <= a[i+1])
suff[i] = suff[i+1] + 1;
else
suff[i] = 1;
}
for(int i=1;i<=n;i++)
{
if(a[i+1] >= a[i-1] && pre[i-1] + suff[i+1] == n-1)
return true;
}
return false;
}
int main()
{
#ifdef local
freopen("in.txt","r",stdin);
#endif // local
int T;
cin >> T;
while(T--)
{
cin >> n;
for(int i=1; i<=n; i++)
cin >> a[i];
a[n+1] = INF;
if(check(0) || check(1))
cout << "YES\n";
else
cout << "NO\n";
}
return 0;
}
18252 Sheep回文串
题意:给你一个字符串,问你最少替换掉多少个字符才能使得原字符串的所有长度为奇数的字串(区分好字串和子序列,字串是要连续的,子序列不需要连续) 为回文串。
看标题显然是某羊出的题。。。应该算思维题吧,分析一下,为了让字符串所有奇数长度的字串都是回文串,其实很容易可以想到最终的字符串肯定是ababababa这种排列的字符串才可以满足要求(当然,aaaaaa)这种当然也是可以的。
知道最终要转换的字符串形式,显然只要对原字符串分奇偶位处理就行了,保留奇数位以及偶数位中出现最多的字符(字母),其他同奇偶的字符去转换,才能得到最小的转换次数。。。。。emmmmm不知道说明白了没有。
还有就是字符串长度较长,最好不要使用string跟cin,亲测cin 667ms,用char 字符串跟scanf 61ms.
#include <iostream>
#include <cstring>
#define ll long long
using namespace std;
const int N = 1000001 + 5;
const int INF = 10000;
int odd[30],even[30];
char s[N];
int main()
{
#ifdef local
freopen("in.txt","r",stdin);
#endif // local
scanf("%s",s);
int len = strlen(s);
for(int i=0;i<len;i++)
if(i & 1) odd[s[i]-'a']++;
else even[s[i]-'a']++;
int oddMax = 0,evenMax = 0;
for(int i=0;i<26;i++)
oddMax = max(oddMax,odd[i]),
evenMax = max(evenMax,even[i]);
cout << len - oddMax - evenMax << endl;
return 0;
}
18242 请问您今天要来点魔法吗??
题意:给你一个从n->m的转换,对n每次抹除最后一位之后求和(其实就是 /10 ),然后反过来给你一个m,让你求n。
题目有个误导你的地方,说如果有多个n满足输出最小的。。。。从/10那个地方就可以明显看出,从n->m的这个装换函数显然是单调的。
而且看到数据范围为1e9,这个范围又是单调,那基本就可以肯定就是二分了0.0。
#include <iostream>
#include <cstring>
#define ll long long
using namespace std;
const int N = 1000001 + 5;
int calc(int x)
{
int sum = 0;
while(x)
{
sum += x;
x /= 10;
}
return sum;
}
int main()
{
#ifdef local
freopen("in.txt","r",stdin);
#endif // local
int T;
cin >> T;
while(T--)
{
int m;
cin >> m;
int L = 0,R = 1e9;
while(L < R)
{
if(L + 1 == R)
break;
int mid = (L + R)/2;
if(calc(mid) > m)
R = mid;
else
L = mid;
}
if(calc(L) == m)
cout << L << endl;
else
cout << -1 << endl;
}
return 0;
}
18240 ACMer不得不知道的事儿(四)
题意:给一些变量定义语句以及赋值语句,让你求出最后又多少个变量定义后没有初始值,并输出以及有初始值的变量的值。
显然是模拟题,有两个点需要注意,第一个点是,假设某一个变量前面给了初始值,但是后面再赋值的时候又将一个不知道值的变量赋值给他的话,这个变量就会从确定值又变成不确定值(这个从样例其实也已经可以看出了,b再赋值之后,又将没有初值的a赋给b,所以b到最后的值也是不确定的)。第二个点是:其实题目也有用红色字体标出,常量的值是int类型,所谓的int类型,当然是包括负数的啦,所以要对符号进行处理一下就可以啦。
#include <iostream>
#include <cstring>
#define ll long long
using namespace std;
const int N = 80 + 5;
int nums[30],vis[30];
char s[N];
int main()
{
#ifdef local
freopen("in.txt","r",stdin);
#endif // local
int n; cin >> n;
getchar();
for(int T=1;T<=n;T++)
{
string s;
getline(cin,s);
int len = s.length();
if(s.find("int") < len)
{
for(int i=s.find("int")+3;i<len;i++)
{
if(s[i] >= 'a' && s[i] <= 'z')
vis[s[i] - 'a' + 1] = 1;
}
}
else if(s.find("=") < len)
{
int pos = s.find("=");
int x = 0,y = 0;
for(int i=0;i<pos;i++)
if(s[i] >= 'a' && s[i] <= 'z')
x = s[i] - 'a' + 1;
for(int i=pos+1;i<len;i++)
if(s[i] >= 'a' && s[i] <= 'z')
y = s[i] - 'a' + 1;
if(y == 0)
{
int sum = 0;
for(int i = pos + 1;i < len;i++)
if(s[i] >= '0' && s[i] <= '9')
sum = sum * 10 + s[i] - '0';
vis[x] = 2;
if(s.find("-") < len)
sum *= -1;
nums[x] = sum;
}
else
{
if(vis[y] == 2)
{
vis[x] = 2;
nums[x] = nums[y];
if(s.find("-") < len)
nums[x] = -nums[x];
}
else if(vis[y] == 1)
vis[x] = 1;
}
}
}
int res = 0;
for(int i=1;i<=26;i++)
if(vis[i] == 1) res++;
cout << res << endl;
for(int i=1;i<=26;i++)
if(vis[i] == 2)
printf("%c=%d\n",'a'+i-1,nums[i]);
return 0;
}
18250 寻找SCAU
题意:求字符串中有多少SCAU子序列(注意这次是子序列而不是字串了)。
动态规划的题目,维护一个状态dp[i],表示以当前字符结尾的(子字符串的个数,有S,SC,SCA,SCAU四种情况),然后对于每一个种情况的递归为: dp[i] = (1...i-1)中所有前一种字符的总和(即如果当前是C就求和1-i-1中所有以S结尾的dp[j],)为了不每次都去求和,可以在每次计算的时候记录一下前面4种情况的总和就完事了。
TAT不大会解释,看代码理解吧。。。
#include <iostream>
#include <cstring>
#define ll long long
using namespace std;
const int N = 100000 + 5;
const int mod = 1e9+7;
ll dp[N];
int main()
{
#ifdef local
freopen("in.txt","r",stdin);
#endif // local
string s; cin >> s;
int len = s.length();
ll cntS,cntC,cntA,cntU;
cntS = cntC = cntA = cntU = 0;
for(int i=0;i<len;i++)
{
if(s[i] == 'S')
{
dp[i] = 1;
cntS = (cntS + dp[i]) % mod;
}
else if(s[i] == 'C')
{
dp[i] = cntS;
cntC = (cntC + dp[i]) % mod;
}
else if(s[i] == 'A')
{
dp[i] = cntC;
cntA = (cntA + dp[i]) % mod;
}
else
{
dp[i] = cntA;
cntU = (cntU + dp[i]) % mod;
}
}
cout << cntU << endl;
return 0;
}