浅浅被c#老师强迫参赛吧,然后浅浅解析一下题木吧
A题:我是先记录最大值,然后用哈希表存储再最后判断是否最大输出的emm
#include
#include
#include
#include
#include
#include
using namespace std;
int arr[20000];
vector ans;
int main()
{
string s;
cin >> s;
int n = s.size();
int maxn = 0;
for (int i = 0; i < n; i++) {
unordered_set st;
string e; int cnt = 0;
for (int j = i; j < n; j++) {
if (st.count(s[j]) != 0)
break;
e += s[j];
st.insert(s[j]);
cnt++;
}
st.clear();
ans.push_back(e);
maxn = max(maxn,cnt);
}
for (auto& ch : ans)
if(ch.size()==maxn)
cout << ch << endl;
return 0;
}
B:无聊题跳0.0
C:这边表示题目太长懒直接不做
D:最大化最小值吧 二分查找
#include
#include
using namespace std;
const int N = 1e3 + 5;
int n, m, ans = 0;
int len[N];
bool f(int mid) {
int index = len[1], ans = 1;//ans就是看看能不能放完全部单词
for (int i = 2; i <= n; i++) {
if (len[i] - index >= mid) {//比较前后两个位置间隔是否符合现在的间隔所以要用数存在上一个
index = len[i];
ans++;
}
}
return ans >= m;
}
int main() {
int l = 0, r = 0;
cin >> n >> m;
len[0] = 0;
for (int i = 1; i <= n; i++) {//记录最大,因为下面二分要缩小距离了
cin >> len[i];
r = max(len[i], r);
}
sort(len + 1, len + n + 1);//二分查找常规排序
while (l < r) {
int mid = (r + l + 1) >> 1;
if (f(mid)) l = mid;//这个表示这个间隔能放完全部单词,但不一定是最长距离所以继续扩大
else r = mid - 1;//表示这个间隔放不完全部单词,间隔太长缩小
}
cout << l << endl;
}
E:数学题,无感跳过0.0
F:这个很常规的题,但是那时候我以为tm我写错了ac不了,后面套了快速幂才过,我只能说狗
我是用了树状数组+差分+快速幂的,别问为什么不用线段树,线段树很长诶
#include
#include
#include
#include
using namespace std;
const int maxn = 100010;
typedef long long LL;
LL a[maxn], d[maxn], di[maxn], sum[maxn], n, m;
LL cb[100001];
long long quick(long long a, long long b, long long mod) {
long long ans = 1;
a %= mod;
while (b) {
if (b & 1) {
ans = (ans * a) % mod;
}
a = (a * a) % mod;
b >>= 1;
}
return ans;
}
int lowbit(int x) {
return x & (-x);
}
void Add(LL a[], LL x, LL d)
{
while (x <= n)
{
a[x] += d;
x += lowbit(x);
}
}
LL Sum(LL a[], LL x)
{
LL sum = 0;
while (x > 0)
{
sum += a[x];
x -= lowbit(x);
}
return sum;
}
int main() {
while (cin >> n >> m) {
memset(a, 0, sizeof(a));
memset(d, 0, sizeof(d));
memset(di, 0, sizeof(di));
memset(sum, 0, sizeof(sum));
for (int i = 1; i <= n; ++i)
cin >> a[i];
for (int i = 1; i <= n; ++i)
sum[i] = sum[i - 1] + a[i];
while (m--)
{
LL k, s, t, a, b;
cin >> k;
if (k == 2) {
cin >> s >> t >> a >> b;
LL val;
val = quick(a,b,442333);
Add(d, s, val);
Add(d, t + 1, -val);
Add(di, s, s * val);
Add(di, t + 1, -val * (t + 1));
}
else {
cin >> s >> t;
LL sum_a = sum[t] + (t + 1) * Sum(d, t) - Sum(di, t);
LL sum_b = sum[s - 1] + s * Sum(d, s - 1) - Sum(di, s - 1);
cout << (sum_a - sum_b) << endl;
}
}
}
return 0;
}
G题:一开始以为是tm最短路,然后想了想n给太小了估计是状压emmm
#include
#include
using namespace std;
const int N = 21, M = 1 << N;
int n;
int f[N][M];
int a[N][N];
int cnt[M];
int ans = 0x3f3f3f;
int main()
{
cin >> n;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
{
cin >> a[i][j];
}
memset(f, 0x3f3f3f, sizeof(f));
f[0][1] = 0;//表示从起点出发,现在这个点的集合有一个了就是0节点[i]表示当前在的节点 【j】是集合
for (int k = 0; k < (1 << n); k++)//枚举每一个状态 就比如 000 001 010 100 101 110 111emmm然后 010 表示访问过了第2个节点
for (int i = 0; i < n; i++)//节点
{
if (k >> i & 1)//表示在节点里面 就是k取第i位看看是不是1 是就表示访问过
for (int j = 0; j < n; j++)
{
if (k >> j & 1 && a[j][i])//表示j到i点之间有路,并且j在集合里面
f[i][k] = min(f[i][k], f[j][k - (1 << i)] + a[i][j]);//表示把这个集合里面的这个i点去掉,已经走到了i点不需要他了
}
}
int ans = 0x3f3f3f;
for (int i = 0; i < n; i++) {
ans = min(ans, f[n-1][(1<
H:常规动态规划,不说;
#include
#include
#include
#include
using namespace std;
const int maxn = 51;
long long dp[maxn];
int main() {
int n;
while (cin >> n)
{
dp[1] = 1, dp[2] = 2;
for (int i = 3; i <= maxn; i++)
{
dp[i] = dp[i - 1] + dp[i - 2];
}
cout << dp[n] << endl;
}
return 0;
}
I:也是常规动态规划注意初始化边界就行
#include
#include
#include
#include
using namespace std;
int mp[101][101];
int dp[101][101];
int main()
{
memset(mp, 0, sizeof(mp));
memset(dp, 0, sizeof(dp));
int n;
cin >> n;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= i; j++)
{
cin >> mp[i][j];
}
}
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= i; j++)
{
dp[i][j]= mp[i][j];
}
}
for (int i = 2; i <= n; i++)
{
for (int j = 1; j <= i; j++)
{
if (j == 1)dp[i][j] = dp[i - 1][j] + mp[i][j];
else if (j == i)dp[i][j] = dp[i - 1][j - 1] + mp[i][j];
else
{
dp[i][j] = dp[i - 1][j - 1] + mp[i][j];
dp[i][j] = max(dp[i][j], dp[i - 1][j] + mp[i][j]);
}
}
}
int ans = 0;
for (int i = 1; i <= n; i++)
{
ans = max(ans, dp[n][i]);
}
cout << ans<
J:求最短路,因为是求任意两点间的距离所以用floy算法;让后记得建双向边就行了
#include
#include
#include
#include
#include
#include
#define ll long long
#define ull unsigned long long
#define INF 0x3f3f3f3f
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef pair PII;
const int N = 10000;
int n, m, k;
int dp[N][N];
void floyd()
{
for (int k = 1; k <= n; k++)
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
dp[i][j] = min(dp[i][j], dp[i][k] + dp[k][j]);
}
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
{
if (i == j)dp[i][j] = 0;
else dp[i][j] = INF;
}
for (int i = 2; i <= n; i++)
{
int x, y, z;
cin >> x >> y >> z;
dp[x][y] = z;
dp[y][x] = z;
}
floyd();
while (m--)
{
int x, y;
cin >> x >> y;
if (dp[x][y] == INF)
cout << dp[y][x] << endl;
else
cout << dp[x][y] << endl;
}
return 0;
}
K:
#include
#include
#include
#include
#include
using namespace std;
string a;
int main()
{
string s;
cin>>s;
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
string res;
for(int i=0;i
L:
#include
#include
#include
using namespace std;
const int N = 3000 + 5;
int a[N][N];
int row[N], col[N];
int n, m;
int main() {
while(scanf("%d%d", &n, &m) != EOF) {
for(int i = 0; i < n; i ++ )
{
row[i] = 0;
}
for(int j = 0; j < m; j ++ ) col[j] = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
scanf("%d", &a[i][j]);
row[i] += a[i][j];//求每一行的最大值
col[j] += a[i][j];//求每一列的最大值
}
}
int ans = 0;
for(int i=0; i
M:好我是菜逼,我以为这题是动态规划没解出来看了看答案是贪心
简单来说就是从前往后推 ,只考虑当前的字符,是就不变,不是就变,后面是啥也影响不了我
#include
#include
#include
#include
using namespace std;
const int N = 1010;
typedef pair PII;
string a,b;
vector q;
void rev(int i){
if(a[i]=='0') a[i]='1';
else a[i]='0';
}
int main()
{
cin>>a>>b;
a="?"+a;
b="?"+b;
bool flag=false;
for(int i=1;i
N题:剪枝
可以dp,dp比较爽,这里用的是dfs
#include
#include
#include
using namespace std;
int n,k;
long res=0;
bool st[210];
void dfs(int sum,int u,int last)
{
if(u==k)
{
if(sum==n) res++;
return ;
}
for(int i=last;i<=n-sum;i++)
{
dfs(sum+i,u+1,i);
st[i]=0;
}
}
int main()
{
cin>>n>>k;
dfs(0,0,1);
cout<