题目链接:点击打开链接
#include<cstdio>
#include<algorithm>
#include<cstring>
#define LL long long
using namespace std;
LL n;
int main()
{
while(~scanf("%I64d",&n))
{
printf("%I64d\n",(n&1?n/2-n:n/2));
}
return 0;
}
题目链接: 点击打开链接
Let's define logical OR as an operation on two logical values (i. e. values that belong to the set {0, 1}) that is equal to 1 if either or both of the logical values is set to 1, otherwise it is 0. We can define logical OR of three or more logical values in the same manner:
where is equal to 1 if some ai = 1, otherwise it is equal to 0.
Nam has a matrix A consisting of m rows and n columns. The rows are numbered from 1 to m, columns are numbered from 1 to n. Element at row i (1 ≤ i ≤ m) and column j (1 ≤ j ≤ n) is denoted as Aij. All elements of A are either 0 or 1. From matrix A, Nam creates another matrix B of the same size using formula:
.
(Bij is OR of all elements in row i and column j of matrix A)
Nam gives you matrix B and challenges you to guess matrix A. Although Nam is smart, he could probably make a mistake while calculating matrix B, since size of A can be large.
The first line contains two integer m and n (1 ≤ m, n ≤ 100), number of rows and number of columns of matrices respectively.
The next m lines each contain n integers separated by spaces describing rows of matrix B (each element of B is either 0 or 1).
In the first line, print "NO" if Nam has made a mistake when calculating B, otherwise print "YES". If the first line is "YES", then also print mrows consisting of n integers representing matrix A that can produce given matrix B. If there are several solutions print any one.
2 2 1 0 0 0
NO
2 3 1 1 1 1 1 1
YES 1 1 1 1 1 1
2 3 0 1 0 1 1 1
YES 0 0 0 0 1 0
题解:重新定义的 “与运算” ,读懂题意就好办了
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int m,n;
bool a[110][110];
bool b[110][110];
int main()
{
while(~scanf("%d %d",&m,&n))
{
for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%d",&b[i][j]);
a[i][j]=1;
}
}
for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++)
{
if(!b[i][j]) // 由题意知,a 矩阵的 i行,k列所有的元素都为 0
{
for(int k=1;k<=n;k++)
a[i][k]=0;
for(int k=1;k<=m;k++)
a[k][j]=0;
}
}
}
bool temp=0;
for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++)
{
if(b[i][j])
{
bool flag=0;
for(int k=1;k<=n;k++)
{
if(a[i][k])
{
flag=1;
break;
}
}
for(int k=1;k<=m;k++)
{
if(a[k][j])
{
flag=1;
break;
}
}
if(!flag) // 找遍所有 i行,j列的元素,如果没有一个为 1,则矩阵错误
{
temp=1;
break;
}
}
}
if(temp) break;
}
if(temp) puts("NO");
else
{
puts("YES");
for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++)
{
printf(j==1?"%d":" %d",a[i][j]);
}
puts("");
}
}
}
return 0;
}
题目链接: 点击打开链接
题意:给你一个字符串,通过 left、right(指针移动)、up、down(字符变化)将它改成一个回文字符串。现在让你求最小的移动次数。
思路:因为每次操作都是移动指针或者改变字符串,所以只需要字符前半部分和后半部分进行比较。首先把需要翻转字符的首末位置、次数记录下来。如果指针不需要来回,一次就可以完成,否则,指针一定是先移动完一边在去另一边,求出最小值就可以。
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int n,p;
char str[100010];
int main()
{
while(~scanf("%d %d",&n,&p))
{
scanf("%s",str+1);
if(p>n/2) p=n+1-p; // 因为下面的比较是在串的前一半进行的,要把 p等效换到左边
bool flag=0;
int st,ed,ans=0;
for(int i=1;i<=n/2;i++)
{
int dif=abs(str[i]-str[n+1-i]);
if(dif)
{
if(!flag)
{
st=i; // 记录串需要改变的第一个位置
flag=1;
}
ed=i; // 记录串需要改变的最后一个位置
ans+=min(dif,26-dif); // 选择最优的 up/down 的次数
}
}
if(ans==0) puts("0");
else if(st>=p) // p在 st的左边
printf("%d\n",ed-p+ans);
else if(ed<=p) // p在 ed的右边
printf("%d\n",p-st+ans);
else // p在中间,需要来回移动
printf("%d\n",min(2*(p-st)+ed-p+ans,2*(ed-p)+p-st+ans)); // 找出移动的最优解
}
return 0;
}
题目链接: 点击打开链接
题意:给一棵树,问它有多少子树,子树的最大权值与最小权值之差不大于d,而且非空。
思路:考虑以每个点作为根结点扩展出一棵树,这个树满足树上所有的节点的权值都不比树根大
且 val [ root ] - val [ v ] < = d,然后可以树型 DP 求以这个点为树根的集合数。如果以 u 为根时扩展的树中包含了与 u 权值相同的 v,那么以 v 为根时便不能包括 u 了,这里需要判重。两节点相等的情况可能重复考虑,规定只能从小标号到大标号或者从大标号到小标号,即可避免重复。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#define LL long long
using namespace std;
const int mod=1000000007;
int d,n,root;
int val[2010];
vector<int> G[2010];
LL dfs(int u,int fa)
{
LL ans=1;
int len=G[u].size();
for(int i=0;i<len;i++)
{
int v=G[u][i];
if(v==fa||val[v]>val[root]||(val[v]==val[root]&&v<root)||val[root]-val[v]>d)
continue;
ans=(ans*(dfs(v,u)+1))%mod;
}
return ans;
}
int main()
{
while(~scanf("%d %d",&d,&n))
{
for(int i=1;i<=n;i++)
scanf("%d",val+i);
for(int i=0;i<2010;i++)
G[i].clear();
for(int i=1;i<n;i++)
{
int a,b;
scanf("%d %d",&a,&b);
G[a].push_back(b);
G[b].push_back(a);
}
LL ans=0;
for(int i=1;i<=n;i++)
{
root=i;
ans=(ans+dfs(i,-1))%mod;
}
printf("%I64d\n",ans);
}
return 0;
}